【问题标题】:invalid conversion from 'signed char*' to 'char*' in sprintfsprintf 中从 'signed char*' 到 'char*' 的无效转换
【发布时间】:2018-10-31 19:50:31
【问题描述】:

好的,我收到了这个错误,我不知道如何解决它: 从 'signed char*' 到 'char*' 的无效转换

Dong (char*)ulStatsAsPercentage 没有帮助。

我在两个 sprintf 语句、每个语句的最后一个参数、第一个 sprintf 语句的 ulStatsAsPercentage 和第二个 sprintf 语句的 pxTaskStatusArray[ x ].ulRunTimeCounter 都收到此错误。

这是我的代码:

  TaskStatus_t *pxTaskStatusArray;
  volatile UBaseType_t uxArraySize, x;
  unsigned long ulTotalRunTime, ulStatsAsPercentage;

  ulStatsAsPercentage =
              pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;

  pxTaskStatusArray = (TaskStatus_t*)pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) );

   if( ulStatsAsPercentage > 0UL )
        {
           sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n",
                             pxTaskStatusArray[ x ].pcTaskName,
                             pxTaskStatusArray[ x ].ulRunTimeCounter,
                             ulStatsAsPercentage );//error at this line
        }
        else
        {
           /* If the percentage is zero here then the task has
           consumed less than 1% of the total run time. */
           sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n",
                  pxTaskStatusArray[ x ].pcTaskName,
                  pxTaskStatusArray[ x ].ulRunTimeCounter );//error here too
        }

这是显示错误的控制台:

../L5_Application/main.cpp:181:60: error: invalid conversion from 'signed char*' to 'char*' [-fpermissive]
                                  (char)ulStatsAsPercentage );

c:\users\alti\downloads\sjsu_dev\toolchain\arm-none-eabi\include\stdio.h:244:5: note:   initializing argument 1 of 'int sprintf(char*, const char*, ...)'
 int _EXFUN(sprintf, (char *__restrict, const char *__restrict, ...)
     ^
../L5_Application/main.cpp:181:60: warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 has type 'int' [-Wformat=]
                                  (char)ulStatsAsPercentage );
                                                            ^
../L5_Application/main.cpp:181:60: warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 has type 'int' [-Wformat=]
../L5_Application/main.cpp:189:74: error: invalid conversion from 'signed char*' to 'char*' [-fpermissive]
                                  pxTaskStatusArray[ x ].ulRunTimeCounter );
                                                                          ^
c:\users\alti\downloads\sjsu_dev\toolchain\arm-none-eabi\include\stdio.h:244:5: note:   initializing argument 1 of 'int sprintf(char*, const char*, ...)'
 int _EXFUN(sprintf, (char *__restrict, const char *__restrict, ...)
     ^

任何帮助将不胜感激。

【问题讨论】:

  • 你在哪一行得到错误?您能否编辑您的问题以用评论标记出来?然后还请复制粘贴完整和完整的错误输出,包括可能的信息说明。当然,请尝试创建一个Minimal, Complete, and Verifiable Example,或者至少告诉我们所有相关变量的声明。
  • pcWriteBuffer 是如何定义的?
  • 并且强制转换ulStatsAsPercentage 不会改变任何东西,这不是所抱怨的(因为变量是整数类型)。
  • @Someprogrammerdude 我编辑了我的问题
  • @rici signed char *pcWriteBuffer

标签: c++ char printf signed


【解决方案1】:

charsigned charunsigned char 是三种不同的类型。 (§6.7.1/1 [basic.fundamental])。它们必须具有相同的大小和对齐方式,并且char 必须与其他两个中的一个实际上相同,但它们仍然是三种不同的类型。

由于整数转换规则,可以在三种字符类型之间进行转换而无需显式转换,因此以下是完全有效的:

int fn(char ch);

int main() {
  signed char c = 'A';
  return fn(c);
}

但是,这并不意味着您可以在 指针 之间转换为不同的字符类型。

int fn(char* ch);

int main(void) {
  signed char c[] = {'A', 0};
  return fn(c);
}

⇒(使用 g++:clang++ 表示“没有匹配的函数用于调用 fn

signed.cc: In function ‘int main()’:
signed.cc:5:14: error: invalid conversion from ‘signed char*’ to ‘char*’ [-fpermissive]
   return fn(c);
              ^
signed.cc:1:5: note:   initializing argument 1 of ‘int fn(char*)’
 int fn(char* ch);
     ^

使用 C 而不是 C++ 编译,这会产生警告(如果指定了 -Wall)而不是错误,因为 C 对不同类型的指针分配更加宽松。

请注意,这与例如在一个架构上期望 long*long long* 调用的函数没有什么不同,其中这两者都是具有相同布局的 64 位 2 的补码算术类型。对于C++来说,不同的类型就是不同的类型。

【讨论】:

    【解决方案2】:

    char 类型(正如*printf("%s", ...) 所期望的那样)具有实现定义的签名。它可以是有符号的也可以是无符号的,这取决于编译器。

    在您的情况下,默认情况下它显然是未签名的。这意味着您不能将 signed char 数组视为字符串。任何signed char 数组或指针都需要将其类型更改为charunsigned char(最佳解决方案),或者您可以强制进行显式转换:

    sprintf( (char*)pcWriteBuffer, ...  // quick & dirty fix
    

    【讨论】:

    • charsigned charunsigned char 是三种不同的类型,尽管第一种与其他一种具有相同的表示形式。 (6.2.5/14 及以下)
    • @rici 是的,但您始终可以“以某种实现定义的方式”安全地在所有 3 种类型之间进行转换。
    • 您可以在charsigned char 之间进行转换。但是char*signed char* 之间没有隐式转换,即使charsigned char 具有相同的表示。因此,编译器抱怨参数类型这一事实并没有说明char 的签名。
    • @rici 我从来没有说过你可以隐含地做到这一点。因此,答案中的演员。
    • 这就是你的第二段所说的。你推断char 是无符号的(基于什么?)然后说这就是为什么“你不能把signed char* 当作一个字符串”。但是signed char* 不能用作字符串函数的参数,而不管char 的符号性如何。您将得到完全相同的错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    • 2017-03-19
    • 1970-01-01
    相关资源
    最近更新 更多