这个(char *)&x cast的行为是否定义明确?

在编写一些C代码时,我遇到了一个小问题,我必须将字符转换为“字符串”(一些内存块,其开头由char *指针给出). @H_403_2@我的想法是,如果设置了一些sourcetr指针(不是NULL),那么我应该将它用作我的“最终字符串”,否则我应该将给定的charcode转换为另一个数组的第一个字符,然后使用它.

@H_403_2@出于这个问题的目的,我们假设变量的类型不能事先改变.换句话说,我不能只将charcode存储为const char *而不是int.

@H_403_2@因为我倾向于懒惰,所以我想:“嘿,我不能只使用角色的地址并将该指针视为字符串吗?”.这是我写的一小段(不要把我的头撞到墙上!):

int charcode    = FOO;   /* Assume this is always valid ASCII. */

char* sourcestr = "BAR"; /* Case #1 */
char* sourcestr = NULL;  /* Case #2 */

char* finalstr  = sourcestr ? sourcestr : (char*)&charcode;
@H_403_2@现在我当然试过了,正如我所料,它确实有效.即使有一些警告标志,编译器仍然很高兴.但是,我有这种奇怪的感觉,这实际上是未定义的行为,我不应该这样做.

@H_403_2@我之所以这么认为是因为char *数组需要以null结尾才能正确打印为字符串(我希望我的是!).然而,我不确定& charcode 1的值是否为零,因此我可能最终会遇到一些缓冲区溢出的疯狂.

@H_403_2@是否有一个实际的原因,它为什么它正常工作,或者我只是幸运在我尝试时在正确的地方得到零?

@H_403_2@(注意,我不是在寻找其他方法来实现转换.我可以简单地使用char tmp [2] = {0}变量,并将我的角色放在索引0处.我也可以使用类似sprintf或snprintf的东西,如果我对缓冲区溢出足够小心.有很多方法可以做到这一点,我只是对这个特定的转换操作的行为感兴趣.)

@H_403_2@编辑:我看到有几个人称这个hackery,我们要明确:我完全同意你的看法.在释放的代码中我实际上做这个是不够的受虐狂.这只是我好奇;)

解决方法

由于以下原因,这是绝对未定义的行为: @H_403_2@>不太可能,但在严格引用标准时要考虑:你不能假设代码将被编译的机器/系统上的sizeof int
>如上所述,您不能假设代码集.例如.在EBCDIC机器/系统上发生了什么?
>很容易说你的机器有一个小端处理器.在大端机器上,由于big-endian内存布局,代码失败.
>因为在许多系统上,char是一个有符号整数,就像int一样,当你的char是一个负值(即在具有8bits char的机器上char> 127)时,如果你在代码中分配值,它可能会因符号扩展而失败下面

@H_403_2@码:

char ch = FOO;
int charcode = ch;
@H_403_2@附:关于第3点:你的字符串确实是NULL终止在一个具有sizeof(int)> sizeof(char)的小端程序机器和具有正值的char,因为int的MSB将为0并且这种endianess的内存布局是LSB-MSB(LSB优先).

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录<future>future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...