C和C++的兼容性问题

anrxhzh 2002-09-19 05:20:58
今天被一个C老手问及这样一个问题:

#include <stdio.h>

int main()
{
char s[1]="0";
printf("%s",s);
}

在C语言中,这个程序是合法的,输出是:0烫汤
而在C++语言中,编译器会报错。
如何处理这个兼容性问题?


...全文
222 点赞 收藏 23
写回复
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tommy 2002-09-23
to tttc(Azure):
在C++中,char*a="ss"是没有问题的。VC、Dev C++都没有问题,这也不是什么未知空间,"ss"就在数据段中
回复
azuretttc 2002-09-23
c与c++在内存管理方面有着很大的不同,c++更安全,c中允许指针指向一个未知空间,如 char* a="ss";,而c++不允许,需要char *a;char b[]="ss";a=b;
所以你的问题大概就是类似的编译器的问题吧!用tc试试!

回复
Tommy 2002-09-22
to lx_cyh(hi):
anrxhzh(百宝箱)已经将C和C++中相关部分的标准文本贴出来了,当然就是语法兼容的问题啦,C中允许这样的语法而C++中不允许。

to cloverplus(老婆,我不敢啦):
不知道你用的是什么编译器呢?如果是VC之类的C++编译器的话,它是按C++标准进行编译的,当然不能通过啦
回复
cloverplus 2002-09-22
to:anrxhzh(百宝箱)
wchar_t a[3]=L"eo";//编译通过
wchar_t a[3]=L"eoa";//不能通过
我现在有点不懂了,请详细解释好吗??
回复
lx_cyh 2002-09-22
to :anrxhzh(百宝箱)
这不是语法兼不兼容的问题,它本身就是错的.只是可能C编译器的检查能力差一些
回复
anrxhzh 2002-09-20
我查了一下资料,可以确认这的确是一个不兼容的语法。曾看过 Bjarne Stroustrup 关于C和C++兼容性问题的几篇论文,本来以为对这类问题有一定的把握,没想到连 Bjarne Stroustrup 也遗漏了这个语法,看来兼容之路任重道远啊。

C++ 标准草案
http://www.cs.unc.edu/~smithja/C++Nov97/www.cygnus.com/misc/wp/nov97/decl.html#dcl.init.string

8.5.2 Character arrays [dcl.init.string]

1 A char array (whether plain char, signed char, or unsigned char) can
be initialized by a string-literal (optionally enclosed in braces); a
wchar_t array can be initialized by a wide string-literal (optionally
enclosed in braces); successive characters of the string-literal ini-
tialize the members of the array. [Example:
char msg[] = "Syntax error on line %s\n";
shows a character array whose members are initialized with a string-
literal. Note that because '\n' is a single character and because a
trailing '\0' is appended, sizeof(msg) is 25. ]

2 There shall not be more initializers than there are array elements.
[Example:
char cv[4] = "asdf"; // error
is ill-formed since there is no space for the implied trailing '\0'.
]

C Programming Language
http://www-ccs.ucsd.edu/c/declare.html#Object%20Initializers

You can initialize an array of any character type by writing a string literal, or an array of wchar_t by writing a wide character string literal, as shorthand for a sequence of character constants. The translator retains the terminating null character only when you initialize an object of incomplete array type. (An object of complete array type is padded as needed with trailing zero initializers.)

For example:

char fail[6] = "fail"; same as {'f', 'a', 'i', 'l', 0, 0}
char bad[] = "bad"; same as {'b', 'a', 'd', '\0'}
wchar_t hai[3] = L"hai"; same as {L'h', L'a', L'i'}
But note:

wchar_t hai[3] = {L'h', L'a', L'i',
'\0'}; INVALID

回复
dhy311 2002-09-20
你写的程序本来就是有问题,“0”里面有两个字节,你怎么能用一个字节来表示,我想c++可能再控制程序出错方面比c改进了一些,这是我的个人观点
回复
xjd5555 2002-09-20
学习
回复
kuusr 2002-09-20
同意楼上所说
回复
lx_cyh 2002-09-20
int main()
{
char s[1]="0";
printf("%s",s);
}

在C语言中,这个程序是合法的,//非也,char s[2]="0";参数真正合法的C程序
回复
stidio_zhougang 2002-09-20
To:楼主。
其实在“”里面的是'0'这个字符ASCII码是48,而不是'\0',及ASCII码值为:0
明白了吗也就是说在这个只有一个元素的数组里面,首字符是'0',而在C语言中是不进行数组边界检查的,他的输出一定要等到'\0'为止,所以输出的是那些乱东西。
回复
liubear 2002-09-20
这说明C++编译器更严格了。
这跟编译器的版本也有关系。如,在VC6上运行得好好的程序,到VC.net上就不行,这种情况我碰到过多次。但最终还是程序上的原因。
说明VC.net比VC6增加了更多的检查。
回复
glassshark 2002-09-19
编译器并没错,你做的是数组初始化,并没规定编译器必须对数组越界检查。
这就好象你非要求所有的女人都不能有性病一样。
回复
flcheng 2002-09-19
既然你认为这个写法是不对的
为什么还要考虑兼容呢?
你觉得,这个编制的程序有什么实际意思,一定要和c++兼容呢?
太灵活的东西,当然就有点夸张
兼容的问题我觉得这个不算。

不然c++混的地方不又少了点了吗?那谁还用呢?
回复
jy0102 2002-09-19
Dev-Cpp:

initializer-string for array of chars is too long
回复
mylove0618 2002-09-19
在c中这个用法很特殊,即定义一个只有一个元素的数组。从现实意义上讲,意义不大。但是从语法上讲确实没有问题。是一种常见的数组初始化的方法。至于没有用'\0'结束,算不上是什么错误。因为库函数中就有这样的例子。当然了,这样不是太安全。可是c语言没有给出一个合理安全的解决办法。至于在c++中,安全性得到了提高,将这个视作了错误处理。个人感觉,c++的做法是正确的。至于如何保证兼容,我觉得没有必要。毕竟继承一种东西的前提是这种东西有价值,能够和本系统的要求不冲突。而这种用法本身价值不大,并且安全性不够好,c++中不继承它是很有道理的。现在强求兼容我觉得没有多少意义。个人观点,楼主勿怪。
回复
qhqstar 2002-09-19
这个程序对未分配的内存进行写操作,在c中这么写是很危险的,
c++检查机制比c更彻底。
回复
blh 2002-09-19
你是用的是什么c编译器???
如果他不报告warning说明c变异期检错恩能力有限,不要告诉我是tc
回复
gosirius 2002-09-19
应该是char s[1] = {'0'};
回复
cwanter 2002-09-19
应该算一个bug吧!
回复
发动态
发帖子
C语言
创建于2007-09-28

6.3w+

社区成员

C语言相关问题讨论
申请成为版主
社区公告
暂无公告