什么是C中的陷阱表示(某些示例可能有帮助)?这适用于C++吗?
float f=3.5;
int *pi = (int*)&f;
Run Code Online (Sandbox Code Playgroud)sizeof(int) == sizeof(float)do f和*pi具有相同的二进制表示/模式?MSVC怎么样?这是我的警告.
Missing sentinel in function call
Run Code Online (Sandbox Code Playgroud)
我怎么能删除它.
我正在使用linux和gcc编译器.
在下面的代码中,*(long*)0=0;与if子句一起使用,但它的目的是什么?
if(r.wid*r.ht < tot)
*(long*)0=0;
Run Code Online (Sandbox Code Playgroud) 我隐约记得几年前读过这篇文章,但我在网上找不到任何参考.
你能给我一个NULL宏没有扩展到0的例子吗?
编辑清晰:今天,它扩展为((void *)0),(0)或(0L).但是,有些架构早已被遗忘,而这种情况并非如此,并且NULL扩展到了不同的地址.就像是
#ifdef UNIVAC
#define NULL (0xffff)
#endif
Run Code Online (Sandbox Code Playgroud)
我正在寻找这样一台机器的例子.
更新以解决问题:
我不是在现行标准的背景下提出这个问题,也不是用不正确的术语来扰乱人们.但是,我接受的答案证实了我的假设:
后来的模型使用了[blah],显然是对所有现存的写得不好的C代码的反应,这些代码做出了错误的假设.
有关当前标准中的空指针的讨论,请参阅此问题.
我知道 C 编译器不需要对 的位表示使用全零NULL,但标准要求它们* *NULL在布尔上下文/比较中使评估为假。因此,下面程序中的第二个 printf将始终输出false.
但我想知道的是:在系统中NULL是*不*全零,将指针值*是*全部为零也值为false布尔上下文/比较?换句话说,将在第一个 printf在下面不断输出的程序true?
或者以稍微不同的方式提问:我可以依靠calloc生成一个在布尔上下文/比较中始终评估为 false 的指针值吗?这个问题的第一个答案用于memset清除long*named的位y,然后继续说这y==0是 UB 因为y可能是“陷阱表示”(无论是什么)。 calloc也只是清除位,所以也许o->p第一个 printf也是UB?
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct { void * p; } obj;
int main() {
obj * o = calloc(sizeof(obj), 1);
assert(o); // assume successful …Run Code Online (Sandbox Code Playgroud) 如果我写
int zero = 0;
void *p1 = (void *)0;
void *p2 = (void *)(int)0;
void *p3 = (void *)(0 /*no-op, but does it affect the next zero?*/, 0);
void *p4 = (void *)zero; // For reference, this is a pointer to address zero
void *p5 = 0; // For reference, this is a null pointer
void *p6 = NULL; // For reference, this is a null pointer
void *p7 = nullptr; // For reference, this is a null pointer …Run Code Online (Sandbox Code Playgroud) 来自 C17 草案 (6.3.2.3 \xc2\xb63):
\n\n\n值为 0 的整型常量表达式,或此类转换为类型的表达式
\nvoid *,称为空指针常量。67)如果将空指针常量转换为指针类型,则生成的指针(称为空指针)保证与任何对象或函数的指针比较不相等。67)该宏
\nNULL在(和其他标头)中定义<stddef.h>为空指针常量 [...]。
由此可见,以下是空指针常量:0, 0UL, (void *)0, (void *)0UL, NULL。
进一步得出以下是空指针:(int *)0, (int *)0UL, (int *)(void *)0, (int *)(void *)0UL, (int *)NULL。有趣的是,这些都不是“空指针常量”;看这里。
以下空指针常量是空指针(因为void *是指针类型,并且0和0UL是空指针常量):(void *)0 …
我们本周在这里遇到了有趣的问题.
我们在C上使用哈佛架构嵌入式平台,该平台具有16位数据地址和32位代码地址.
使用函数指针时会出现此问题.如果你有像这样的代码
if (fp) fp();
Run Code Online (Sandbox Code Playgroud)
要么
if (fp != 0) fp();
Run Code Online (Sandbox Code Playgroud)
一切都好.
但是如果你有像这样的代码
if (fp != NULL) fp();
Run Code Online (Sandbox Code Playgroud)
然后,因为NULL定义为(void *) 0,编译器(在这种情况下为gcc)a)不警告,b)对函数指针进行16位比较而不是32位比较.只要你的函数指针没有发生在64k边界上,所以所有底部的16位都是0就很好.
目前我们有大量的代码包含对NULL的显式检查.它们中的大多数将是数据指针,但其中一些将是函数指针.快速grep != NULL或== NULL显示超过3000个结果,许多人通过手动检查.
那么,我们现在想要的也是
找到比较函数指针(但不是数据指针)的所有情况的方法(所以我们可以将它们与我们定义为32位0的FP_NULL进行比较),或者
以这样的方式重新定义NULL,以便它做正确的事情.
(或者,我想,更新我们的gcc端口以检测并正确处理这种情况).
我无法想到任何适用于1的方法.我能想到的唯一方法是将NULL重新定义为0函数指针,这对于绝大多数针对数据指针的比较来说都是非常浪费的.(32位比较是4条指令,16位比较是1条指令).
有什么想法或建议吗?