相关疑难解决方法(0)

C中空指针的指针算法

当一个指针到特定类型的(比如int,char,float,..)被递增,其值增加该数据类型的大小.如果void指向大小数据的指针x递增,它如何获得指向x前面的字节?编译器如何知道添加x指针的值?

c pointers void-pointers pointer-arithmetic

162
推荐指数
7
解决办法
11万
查看次数

使用stddef.h的offsetof而不是滚动自己的可移植性

这是一个挑剔的细节问题,有三个部分.上下文是我希望说服一些人无条件地使用无条件<stddef.h>的定义offsetof而不是(在某些情况下)滚动他们自己的定义是安全的.有问题的程序完全用普通的旧C编写,所以在回答时请完全忽略C++.

第1部分:当以与标准相同的方式使用时offsetof,此宏的扩展是否会引发每个C89的未定义行为,为什么或为什么不行,并且它在C99中是不同的?

#define offset_of(tp, member) (((char*) &((tp*)0)->member) - (char*)0)
Run Code Online (Sandbox Code Playgroud)

注意:人们感兴趣的所有实现都取代了标准的规则,指针只有在指向同一个数组时才能相互减去,通过定义所有指针,无论类型或值,指向单个指针全球地址空间.因此,在争论这个宏的扩张引发未定义的行为时,请不要依赖于该规则.

第2部分:据您所知,有没有一个已发布的生产C实现,当进行上述宏的扩展时,(在某些情况下)会表现出与offsetof使用其宏时的情况不同的行为?

第3部分:据您所知,最近发布的生产C实现是什么,或者未提供stddef.h或未提供offsetof该标题中的工作定义?该实现是否声称符合任何版本的C标准?

对于第2部分和第3部分,请仅在您可以命名特定实现并给出发布日期时回答.说明可能符合条件的实现的一般特征的答案对我没用.

c standards portability

12
推荐指数
2
解决办法
3027
查看次数

__builtin_offsetof运算符的用途和返回类型是什么?

C++中__builtin_offsetof运算符(或Symbian中的_FOFF运算符)的用途是什么?

它还有什么回报?指针?字节数?

c++ symbian

7
推荐指数
3
解决办法
9355
查看次数

这会避免UB吗?

这个问题更像是一个学术问题,因为没有正当理由再写自己的offsetof宏了.不过,我已经在这里和那里看到了这个本土实现的弹出窗口:

#define offsetof(s, m) ((size_t) &(((s *)0)->m))
Run Code Online (Sandbox Code Playgroud)

从技术上讲,这是取消引用NULL指针(AFAIKT):

C11(ISO/IEC 9899:201x)§6.3.2.3指针第3节

具有该值的整数常量表达式0或此类表达式转换为类型 void *称为空指针常量

所以上面的实现是根据我如何阅读标准,与写作相同:

#define offsetof(s, m) ((size_t) &(((s *)NULL)->m))
Run Code Online (Sandbox Code Playgroud)

它让我怀疑的是,通过改变一个微小的细节,下面的定义offsetof是完全合法的,可靠的:

#define offsetof(s, m) (((size_t)&(((s *) 1)->m)) - 1)
Run Code Online (Sandbox Code Playgroud)

看起来,而不是0,1用作指针,我在结尾处减去1,结果应该是相同的.我不再使用NULL指针了.据我所知,结果是一样的.

所以基本上:有没有理由为什么使用1而不是0在这个offsetof定义中可能不起作用?在某些情况下它仍会导致UB,如果是这样的话:何时以及如何?基本上,我在这里问的是:我在这里错过了什么吗?

c undefined-behavior language-lawyer

5
推荐指数
1
解决办法
145
查看次数