Why is passing a string literal into a char* argument only sometimes a compiler error?(为什么将字符串文字传递给 char* 参数有时只是编译器错误?)
问题描述
我正在使用 C 和 C++ 程序.我们曾经在没有 make-strings-writable 选项的情况下进行编译.但那会收到一堆警告,所以我把它关掉了.
I'm working in a C, and C++ program. We used to be compiling without the make-strings-writable option. But that was getting a bunch of warnings, so I turned it off.
然后我收到一大堆错误,形式为无法在函数 foo 的参数 3 中将 const char* 转换为 char*".所以,我经历了很多改变来解决这些问题.
Then I got a whole bunch of errors of the form "Cannot convert const char* to char* in argmuent 3 of function foo". So, I went through and made a whole lot of changes to fix those.
但是,今天,程序崩溃了,因为文字"被传递到一个期待 char* 的函数中,并将第 0 个字符设置为 0.它没有做任何坏事,只是试图编辑一个不断的,崩溃的.
However, today, the program CRASHED because the literal "" was getting passed into a function that was expecting a char*, and was setting the 0th character to 0. It wasn't doing anything bad, just trying to edit a constant, and crashing.
我的问题是,为什么这不是编译器错误?
My question is, why wasn't that a compiler error?
如果重要的话,这是在使用 gcc-4.0 编译的 mac 上.
In case it matters, this was on a mac compiled with gcc-4.0.
添加代码:
char * host = FindArgDefault("EMailLinkHost", "");
stripCRLF(linkHost, '
');
地点:
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...
This compiled and ran until it tried to set *q to 0...
编辑 2:
大多数人似乎都没有抓住我的问题的重点.我知道为什么 char foo[] = "bar" 有效.我知道为什么 char * foo = "bar";不起作用.
Most people seem to be missing the point of my question. I know why char foo[] = "bar" works. I know why char * foo = "bar"; doesn't work.
我的问题主要是关于传递参数.我想到的一件事是这可能是 C 与 C++ 的问题吗?"因为我有一些 .c 文件和一些 .cpp 文件,而且 C 很可能允许它,但 C++ 不允许......反之亦然......
My question is mostly with respect to passing parameters. One thing that occures to me is "Is it possible that this is a C vs C++ issue?" because I have some .c files and some .cpp files, and it's quite possible that C allows it, but C++ doesn't... or vice versa...
推荐答案
标准规定了一个特殊的规则,允许字面量到 char*
的转换,它悄悄地丢弃了 const
资格.(4.2/2):
The standard specifies a special rule allowing the literal-to-char*
conversion which quietly drops const
qualification. (4.2/2):
不是宽字符串文字的字符串文字(2.13.4)可以转换为pointer to char"类型的右值;宽字符串文字可以转换为指向 wchar_t 的指针"类型的右值.无论哪种情况,结果都是指向数组第一个元素的指针.仅当存在显式适当的指针目标类型时才考虑这种转换,而不是当一般需要从左值转换为右值时.[注意:此转换已弃用.见附录 D.]
A string literal (2.13.4) that is not a wide string literal can be converted to an rvalue of type "pointer to char"; a wide string literal can be converted to an rvalue of type "pointer to wchar_t". In either case, the result is a pointer to the first element of the array. This conversion is considered only when there is an explicit appropriate pointer target type, and not when there is a general need to convert from an lvalue to an rvalue. [Note: this conversion is deprecated. See Annex D. ]
C++0x 标准进一步弃用了这一点……这条废话规则已从即将发布的标准中完全删除.
The C++0x standard takes that deprecation further… this nonsense rule is removed entirely from the upcoming standard.
const char*
到 char*
错误必须是先将文字转换为 const char*
的结果.
The const char*
to char*
error must be a result of converting a literal to a const char*
first.
这篇关于为什么将字符串文字传递给 char* 参数有时只是编译器错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么将字符串文字传递给 char* 参数有时只是编译器错误?
基础教程推荐
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07