如何在C中编译时打印sizeof()的结果?
现在我使用静态断言(基于其他Web资源自酿)来将sizeof()结果与各种常量进行比较.虽然这有效但它远非优雅或快速.我还可以创建变量/ struct的实例并查看映射文件,但这比直接调用/命令/运算符更不优雅和快速.此外,这是一个使用多个交叉编译器的嵌入式项目......因此,为目标构建和加载示例程序然后读出一个值比上述任何一个都更麻烦.
在我的情况下(旧的GCC),#warning sizeof(MyStruct)在打印警告之前实际上并没有解释sizeof().
建立
给定此用户定义的类型:
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是多态的,那么这不会影响这一点,因为静态成员不能是虚拟的.