Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 计算任意类型';在不执行程序的情况下改变大小_C_Types_Compilation_Sizeof - Fatal编程技术网

C 计算任意类型';在不执行程序的情况下改变大小

C 计算任意类型';在不执行程序的情况下改变大小,c,types,compilation,sizeof,C,Types,Compilation,Sizeof,给定C程序中的任何类型,我想知道它的大小,比如执行下面一行时 printf("%d\n",sizeof(myType)); 没有实际执行程序。该解决方案必须适用于大小可以在编译时确定的任意类型,例如用户定义的结构 其基本原理是,如果可以在编译时知道这些信息,那么应该有一种方法可以在不运行程序的情况下提取这些信息。可能是比解析结果汇编程序源代码或二进制文本常量更优雅的方法,但如果这是唯一的方法,我会尽我所能 这对我来说不太管用,因为OP的解决方案依赖于执行代码,而投票最多的答案依赖于实际扩展宏的

给定C程序中的任何类型,我想知道它的大小,比如执行下面一行时

printf("%d\n",sizeof(myType));
没有实际执行程序。该解决方案必须适用于大小可以在编译时确定的任意类型,例如用户定义的结构

其基本原理是,如果可以在编译时知道这些信息,那么应该有一种方法可以在不运行程序的情况下提取这些信息。可能是比解析结果汇编程序源代码或二进制文本常量更优雅的方法,但如果这是唯一的方法,我会尽我所能

这对我来说不太管用,因为OP的解决方案依赖于执行代码,而投票最多的答案依赖于实际扩展宏的预处理器信息指令(我的工具链显然没有)

作为背景,我正在为PIC18 MCU开发并使用XC8编译器

我最终想要的是验证我定义的一些结构在内存中占用了它们的预期大小

这是静态断言的经典用例。如果编译器支持
\u Static\u assert
,则可以编写

_Static_assert(sizeof(mystruct) == expected_size, "Invalid struct size.");

如果您使用的旧编译器尚不支持C-1x,请使用依赖于声明大小为负的数组类型的通用解决方案:

#define CHECK_SIZE(x,e) if(sizeof(char[2*(sizeof(x)==e)-1])==1);

我最终想要的是验证我定义的一些结构在内存中占用了它们的预期大小

这是静态断言的经典用例。如果编译器支持
\u Static\u assert
,则可以编写

_Static_assert(sizeof(mystruct) == expected_size, "Invalid struct size.");

如果您使用的旧编译器尚不支持C-1x,请使用依赖于声明大小为负的数组类型的通用解决方案:

#define CHECK_SIZE(x,e) if(sizeof(char[2*(sizeof(x)==e)-1])==1);


看看生成的汇编代码?否则,只需阅读ABI并自己收集信息。听起来像个XY问题。你到底想要实现什么?你为什么要这样做?你想要这个做什么?你可以用这个。非常方便。正确的方法是静态断言。或者也不要依赖于此,而是编写正确的代码,剩下的留给编译器。@EugeneSh:如果有标准版本,请不要直接使用非标准补丁。请参见
\u Static\u assert
@Olaf并非每个编译器都遵循最新的标准,您知道……请查看生成的汇编代码?否则,只需阅读ABI并自己收集信息。听起来像个XY问题。你到底想要实现什么?你为什么要这样做?你想要这个做什么?你可以用这个。非常方便。正确的方法是静态断言。或者也不要依赖于此,而是编写正确的代码,剩下的留给编译器。@EugeneSh:如果有标准版本,请不要直接使用非标准补丁。请参阅
\u Static\u assert
@Olaf并非所有编译器都遵循最新标准,您知道这一点…>
如果您使用的是不支持C-1x的旧编译器,请使用依赖于声明大小为负的数组类型的通用解决方法。
谢谢!我想这可能会奏效,所以我试了一下。不幸的是,我的编译器不合作,并且会很高兴地编译您的demo2代码(考虑到类型大小的差异)。它还将执行诸如
struct s{int8_t a;}
typedef char pass_断言[sizeof(struct s)==20]//我理解这将产生空字节
,同时它将拒绝
typedef char fail_断言[0]
@DanielArmengod当表达式为false时,括号中的表达式将变为负值。编译器将接受零大小的数组,但必须拒绝负大小的数组。要在编译器中尝试这一点,请创建一个
typedef char foo[-1]并查看编译器的反应。我的编译器拒绝接受维度为0的数组。它生成以下错误消息:
newmain.c:3:error:(284)无效维度
(使用
typedef char a[0]
进行测试)@DanielArmengod如果没有
if
,即
定义检查大小(x,e)typedef char SIZE\u检查[2*(sizeof(x)==e)-1]
,则会发生什么情况?最后一个建议有效!非常感谢。我真的不明白为什么它在if条件下不工作。我做了一些测试,发现如果被测试的变量有一个基本类型(例如char,long),它会正常工作,但是如果它是
struct X
类型,那么不管该结构是什么,不管你检查的是什么大小,它都不会触发。>
如果你使用的是不支持C-1x的旧编译器,使用依赖于声明大小为负的数组类型的常见解决方法
谢谢!我想这可能会奏效,所以我试了一下。不幸的是,我的编译器不合作,并且会很高兴地编译您的demo2代码(考虑到类型大小的差异)。它还将执行诸如
struct s{int8_t a;}
typedef char pass_断言[sizeof(struct s)==20]//我理解这将产生空字节
,同时它将拒绝
typedef char fail_断言[0]
@DanielArmengod当表达式为false时,括号中的表达式将变为负值。编译器将接受零大小的数组,但必须拒绝负大小的数组。要在编译器中尝试这一点,请创建一个
typedef char foo[-1]并查看编译器的反应。我的编译器拒绝接受维度为0的数组。它生成以下错误消息:
newmain.c:3:error:(284)无效维度
(使用
typedef char a[0]
进行测试)@DanielArmengod如果没有
if
,即
定义检查大小(x,e)typedef char SIZE\u检查[2*(sizeof(x)==e)-1]
,则会发生什么情况?最后一个建议有效!非常感谢。我真的不明白为什么它在if条件下不工作