相关疑难解决方法(0)

&((struct name*)NULL - > b)是否会在C11中导致未定义的行为?

代码示例:

struct name
{
    int a, b;
};

int main()
{
    &(((struct name *)NULL)->b);
}
Run Code Online (Sandbox Code Playgroud)

这是否会导致未定义的行为?我们可以辩论它是否"取消引用无效",但是C11没有定义术语"解除引用".

6.5.3.2/4明确指出*在空指针上使用会导致未定义的行为; 但它并没有说同样的->,也没有定义a -> b(*a).b; 它为每个运营商分别定义.

->6.5.2.3/4中的语义说:

后缀表达式后跟 - >运算符和标识符指定结构或联合对象的成员.该值是第一个表达式指向的对象的指定成员的值,并且是左值.

但是,NULL并没有指向一个对象,所以第二句似乎没有说明.

相关的可能是6.5.3.2/1:

约束:

一元运算&符的操作数应该是函数指示符,[]一元或一元运算*符的结果 ,或者是一个左值,它指定一个不是位字段的对象,并且不用寄存器存储类说明符声明.

但是我觉得粗体文本是有缺陷的并且应该读取可能指定对象的左值,按照6.3.2.1/1(左值的定义) - C99弄乱了左值的定义,所以C11必须重写它,也许这个部分错过了.

6.3.2.1/1确实说:

左值是一个表达式(对象类型不是void)可能指定一个对象; 如果左值在评估时未指定对象,则行为未定义

&操作员确实评估了它的操作数.(它不访问存储的值,但这是不同的).

这种长期推理似乎表明代码会导致UB,但它相当脆弱,我不清楚标准的作者是什么意图.如果事实上他们打算做任何事情,而不是让我们讨论:)

c offsetof language-lawyer c11

57
推荐指数
4
解决办法
3483
查看次数

通过无效指针访问静态成员:保证"工作"?

建立

给定此用户定义的类型:

struct T
{
    static int x;
    int y;

    T() : y(38);
};
Run Code Online (Sandbox Code Playgroud)

并在某处有用的必要定义:

int T::x = 42;
Run Code Online (Sandbox Code Playgroud)

以下是将标准int值传递给stdout的规范方法:

std::cout << T::x;
Run Code Online (Sandbox Code Playgroud)

控制

同时,由于T不存在的实例,以下(当然)无效:

T* ptr = NULL; // same if left uninitialised
std::cout << ptr->y;
Run Code Online (Sandbox Code Playgroud)

现在考虑以下代码的可怕和邪恶和坏:

T* ptr = NULL;
std::cout << ptr->x; // remember, x is static
Run Code Online (Sandbox Code Playgroud)

ptr如上所述,取消引用无效.即使这里没有物理内存解除引用,我相信它仍然算作一个,使上面的代码UB.或者......是吗?

14882:2003 5.2.5/3明确表示a->b转换为(*(a)).b,并且:

评估点或箭头之前的后缀表达式; 即使结果不必确定整个后缀表达式的值,也会发生此评估,例如,如果id-expression表示静态成员.

但目前尚不清楚这里的"评估"是否涉及实际的解除引用.实际上,14882:2003和n3035似乎都没有明确地说明指针表达式在处理静态成员时是否必须求值为指向有效实例的指针.

我的问题是,这有多么无效?它是否真的被标准特别禁止(即使没有物理解除引用),或者它只是我们可以逃脱的语言的怪癖?即使它被禁止,我们还期望GCC/MSVC/Clang在多大程度上安全地对待它?

我的g ++ 4.4似乎生成的代码永远不会尝试将[invalid] this指针推入堆栈,并关闭优化.

BTW如果T是多态的,那么这不会影响这一点,因为静态成员不能是虚拟的.

c++

9
推荐指数
1
解决办法
862
查看次数

C和C++标准是否意味着地址空间中的特殊值必须仅存在才能表示空指针的值?

在关于C和C++中的空指针的这个问题的讨论之后,我想在这里分开结束问题.

如果可以从C和C++标准推断(答案可以针对两个标准),取消引用其值等于nullptr(或(void *)0)值的指针变量是未定义的行为,是否意味着这些语言需要地址中的特殊值空间已经死了,这意味着它除了代表的作用外无法使用nullptr?如果系统在相同的地址处具有真正有用的功能或数据结构,该nullptr怎么办?这应该永远不会发生,因为编译器编写的每个系统都需要找出一个非冲突的空指针值,这是编译器的编写者责任吗?或者,在"未定义的行为模式"下编程以实现其意图时,需要访问此类函数或数据结构的程序员是否满足?

这看起来模糊了编译器和计算机系统角色的界限.我会问这样做是否正确,但我想这里没有空间.

这篇博文详细介绍了解决问题的情况

c c++ systems-programming language-lawyer

0
推荐指数
1
解决办法
798
查看次数

标签 统计

c ×2

c++ ×2

language-lawyer ×2

c11 ×1

offsetof ×1

systems-programming ×1