GCC编译器并将const char*转换为char*

Kee*_*eto 4 c gcc build literals

我正在尝试构建M-SIM架构模拟器,但是当我运行make实用程序时,gcc会报告此错误(它甚至不是警告)

注意:预期'char*'但参数类型为'const char*'

因为这被认为是一个错误.是否有任何标志可以绕过此检查?

Kei*_*son 9

这是一个错误,因为将const char*参数传递给带参数的函数会char*违反const-correctness; 它会允许你修改一个const对象,这会破坏整个目的const.

例如,这个C程序:

#include <stdio.h>

void func(char *s) {
    puts(s);
    s[0] = 'J';
}

int main(void) {
    const char message[] = "Hello";
    func(message);
    puts(message);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

从gcc生成以下编译时诊断:

c.c: In function ‘main’:
c.c:10:5: warning: passing argument 1 of ‘func’ discards qualifiers from pointer target type
c.c:3:6: note: expected ‘char *’ but argument is of type ‘const char *’
Run Code Online (Sandbox Code Playgroud)

最后的消息被标记为"注释",因为它引用了(完全合法的)声明func(),解释了这是警告所引用的参数声明.

就C标准而言,这是一种约束违规,这意味着编译器可以将其视为致命错误.GCC,默认情况下,只是发出警告,并从中做一个隐式转换const char*char*.

当我运行程序时,输出是:

Hello
Jello
Run Code Online (Sandbox Code Playgroud)

这表明,即使我宣布messageconst,该功能能够对其进行修改.

由于gcc没有将此视为致命错误,因此无需抑制任何诊断消息.完全有可能代码仍然可以工作(例如,如果函数没有发生任何修改).但警告存在是有原因的,你或M-SIM架构模拟器的维护人员应该看看这个.

(传递字符串文字func()不会触发这些诊断,因为C不会将字符串文字视为const.(它确实使得尝试修改字符串文字的行为未定义.)这是出于历史原因.gcc确实有一个选项,, -Wwrite-strings这会导致它将字符串文字视为const;这实际上违反了C标准,但它可以是一个有用的检查.)

正如我在评论中提到的那样,如果您向我们展示触发诊断的代码,将会很有帮助.

我自己甚至下载并构建了M-SIM架构模拟器,但我没有看到那个特定的消息.


R..*_*R.. 5

指向const限定类型的指针不会隐式转换为指向非const限定类型的指针。必须通过强制转换进行显式转换,例如:

foo((char *)bar)
Run Code Online (Sandbox Code Playgroud)