为什么有时将字符串文字传递给char*参数只是编译器错误?

Bri*_*tow 7 c c++ const char string-literals

我正在使用C和C++程序.我们曾经在没有make-strings-writable选项的情况下进行编译.但是这得到了一堆警告,所以我把它关掉了.

然后我得到了一堆形式的错误"无法将const char*转换为函数foo的argmuent 3中的char*".所以,我经历了很多修改来解决这些问题.

然而,今天,程序崩溃,因为文字""被传递到一个期待char*的函数,并将第0个字符设置为0.它没有做任何坏事,只是试图编辑一个常量,并且崩溃.

我的问题是,为什么不是编译器错误?

如果它很重要,这是在使用gcc-4.0编译的mac上.

编辑:添加代码:

char * host = FindArgDefault("EMailLinkHost", "");
stripCRLF(linkHost, '\n');
Run Code Online (Sandbox Code Playgroud)

哪里:

char *FindArgDefault(char *argName, char *defVal) 
{// simplified
    char * val = defVal;
    return(val);
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

这编译并运行,直到它试图将*q设置为0 ...

编辑2:

大多数人似乎都忽略了我的问题.我知道为什么char foo [] ="bar"有效.我知道为什么char*foo ="bar"; 不起作用.

我的问题主要是关于传递参数.有一件事发生在我身上:"这可能是C与C++的问题吗?" 因为我有一些.c文件和一些.cpp文件,C很可能允许它,但是C++没有......反之亦然......

Pot*_*ter 8

该标准规定了一个特殊的规则,允许文字char*转换悄然降低const资格.(4.2/2):

不是宽字符串文字的字符串文字(2.13.4)可以转换为"指向字符的指针"的右值; 可以将宽字符串文字转换为"指向wchar_t的指针"类型的右值.在任何一种情况下,结果都是指向数组第一个元素的指针.仅当存在明确的适当指针目标类型时才考虑此转换,而不是在通常需要从左值转换为右值时.[注意:此转换已弃用.见附件D.]

C++ 0x标准进一步采用了这种弃用...这个无意义的规则完全从即将推出的标准中删除.

const char*char*误差必须转换字面到的结果const char*第一.


AnT*_*AnT 6

使用字符串文字char *在C++中初始化指针是一个不推荐使用的功能,但它是合法的.这不是错误.您有责任确保不通过此类指针进行任何修改尝试.

换句话说,你必须误解你之前得到的编译错误.对于这样的初始化/分配,我认为你没有任何错误.您在问题中提到的"无法将const char*转换为char*"错误必须由其他内容生成.

请注意,您可以char *使用字符串文字初始化指针并不意味着您可以使用任意const char *值来初始化char *指针.这段代码

const char *pc = "A";
char *p = pc;
Run Code Online (Sandbox Code Playgroud)

会产生错误,而这个

char *p = "A";
Run Code Online (Sandbox Code Playgroud)

将不会.上述不推荐使用的功能仅适用于字符串文字,不适用于所有const char *指针.