我遇到了一个不可移植的C代码示例,其中char指针是变量C函数的参数。下面的图像描述了该示例。用蓝色突出显示的部分不一定清晰,而且看起来是错误的。特别是,我有两个问题:
char *string = NULL时不会执行32位int到64位0的隐式转换。如果不是,那么我们是不是说像char *string = NULL这样的表达式都是不可移植的,必须始终用char *string = (char *)NULL这样的显式强制转换来替换便携C?。

截图来源:https://wiki.sei.cmu.edu/confluence/plugins/servlet/mobile?contentId=87152357#content/view/87152357
发布于 2022-04-12 11:42:42
引用的文章是错误的,应该置之不理。
假设在系统上NULL为32位int 0,编译器将不会在遇到char *string = NULL.时执行32位int到64位0的隐式转换。
赋值自动将右操作数转换为左操作数的类型。因此,char *string = NULL将将NULL值转换为char *,而不是将其转换为“64位0”。
如果不是
,那么我们是说像
char *string = NULL这样的每个表达式都是不可移植的,必须总是用可移植C的显式强制转换(如char *string = (char *)NULL)来替换吗?
不,char *string = NULL是可移植的C代码;它是严格一致的。
引用的代码( char* string = NULL;后面跟着printf("%s %d\n", string, 1); )不将NULL传递给printf。它将string传递给printf,而先前的赋值将NULL转换为char *。因此,printf被传递给一个具有空指针值的char *。这不会在将变量参数解释为printf时造成任何问题。(但是,传递用于%s转换的空指针是不适当的。)
如果调用是printf("%s", NULL);,那么就会出现问题。与变量参数函数的...部分对应的参数不会自动转换为参数类型。它们由默认参数提升处理,主要是将窄整数类型提升为int,将float提升为double,但不会将int转换为任何类型的指针。因此,如果NULL被定义为0,那么printf("%s", NULL);将传递一个int,其中期望有一个char *,这可能会导致对参数的各种错误解释。
因此,永远不要使用NULL宏作为带有变量参数列表的函数的直接参数。使用从NULL分配的指针变量是可以的。
https://stackoverflow.com/questions/71837742
复制相似问题