【发布时间】:2011-02-15 04:09:18
【问题描述】:
我正在使用 C 和 C++ 程序。我们曾经在没有 make-strings-writable 选项的情况下进行编译。但那会收到一堆警告,所以我把它关掉了。
然后我收到一大堆错误,形式为“无法在函数 foo 的参数 3 中将 const char* 转换为 char*”。所以,我经历了很多改变来解决这些问题。
然而,今天,程序崩溃了,因为文字“”被传递到一个期待 char* 的函数中,并将第 0 个字符设置为 0。它没有做任何坏事,只是试图编辑一个不断的,崩溃的。
我的问题是,为什么这不是编译器错误?
如果重要的话,这是在使用 gcc-4.0 编译的 mac 上。
编辑:添加代码:
char * host = FindArgDefault("EMailLinkHost", "");
stripCRLF(linkHost, '\n');
地点:
char *FindArgDefault(char *argName, char *defVal)
{// simplified
char * val = defVal;
return(val);
}
和
void stripCRLF(char *str, char delim)
{
char *p, *q;
for (p = q = str; *p; ++p) {
if (*p == 0xd || *p == 0xa) {
if (p[1] == (*p ^ 7)) ++p;
if (delim == -1) *p = delim;
}
*q++ = *p;
}
*q = 0; // DIES HERE
}
编译并运行,直到它尝试将 *q 设置为 0...
编辑 2:
大多数人似乎都没有抓住我的问题的重点。我知道为什么 char foo[] = "bar" 有效。我知道为什么 char * foo = "bar";不起作用。
我的问题主要是关于传递参数。我想到的一件事是“这可能是 C 与 C++ 的问题吗?”因为我有一些 .c 文件和一些 .cpp 文件,C 很可能允许这样做,但 C++ 不允许……反之亦然……
【问题讨论】:
-
你有示例代码我们可以看看吗?
-
经验法则是您应该始终将字符串文字视为 const char *。将它们视为 char * 会使您面临这些问题。
-
@matteo:当然。我的问题是为什么编译器会捕获其中一些,但不是全部...
-
您添加的代码的行为完全合乎逻辑。是的,这应该编译并运行,直到您尝试修改某些内容。但是,据我了解,您的主要问题是编译器检测到一些错误而未能检测到其他一些错误。这是其中一个“失败”的。现在向我们展示一个成功“检测到”的。
-
那里有三个函数。调用一个函数来返回一个指向字符串文字的指针并将其分配给
char *,然后调用一个函数来修改它。您并没有让编译器轻松找出正在发生的事情。致命的转换是调用FindArgDefault(),其他一切都是正确的。有很多旧代码不是 const 正确的,根据标准,允许将字符串文字传递给char *(尽管尝试更改它的未定义行为)。我认为你对 gcc 的期望太高了。
标签: c++ c char constants string-literals