sizeof() 不由预处理器执行

发布于 2024-11-09 05:29:56 字数 226 浏览 0 评论 0原文

#if sizeof(int) != 4
/* do something */

#if 内使用 sizeof 不起作用,而在 #define 内使用 sizeof 则有效,为什么?

#define size(x) sizeof(x)/sizeof(x[0]) /*works*/
#if sizeof(int) != 4
/* do something */

Using sizeof inside #if doesn't work while inside #define it works, why?

#define size(x) sizeof(x)/sizeof(x[0]) /*works*/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

流年里的时光 2024-11-16 05:29:56

没有什么是邪恶的——一切都可能被滥用,或者在你的情况下被误解。 sizeof 运算符是编译器功能,但编译器功能不可用于预处理器(在编译器介入之前运行),因此不能在 #if 预处理器中使用指令。

但是,当您说:

#define size(x) sizeof(x)/sizeof(x[0])

并使用它时:

size(a)

预处理器执行传递给编译器的文本替换:

sizeof(a)/sizeof(a[0])

Nothing is evil - everything can be misused, or in your case misunderstood. The sizeof operator is a compiler feature, but compiler features are not available to the preprocessor (which runs before the compiler gets involved), and so cannot be used in #if preprocessor directives.

However, when you say:

#define size(x) sizeof(x)/sizeof(x[0])

and use it:

size(a)

the preprocessor performs a textual substitution that is handed to the compiler:

sizeof(a)/sizeof(a[0])
漆黑的白昼 2024-11-16 05:29:56

C“预处理器”宏仅计算常量和其他宏

简单的答案是预处理器表达式仅对由其他预处理器宏和常量组成的表达式提供有意义的计算。

试试这个,您将 得到一个错误:

#if sizeof < 2
int f(int x) { return x; }
#endif

如果你生成程序集,你会发现 sizeof < 2 编译该函数,而 sizeof >= 2 则不编译。两者都不返回错误。

这是怎么回事?事实证明,除了预处理器宏本身之外,预处理器(“宏”)表达式中的所有标识符都被替换为 0。因此上面的 #if 等同于:

#if Easter_Bunny < 2

or

#if 0 < 2

这就是为什么你在预处理器表达式中错误地使用 sizeof 运算符时,实际上不会出现任何类型的错误。

碰巧,sizeof 是一个运算符,但它也是一个标识符,并且本身不是宏的标识符在预处理器表达式中都会变成 0。至少在概念上,预处理器在编译器之前运行。它可以将非 C 语法转换为 C 语法,因此在运行时,C 程序甚至还没有被解析。目前还不可能引用实际的 C 对象:它们不存在。

当然,定义的替换文本中的 sizeof 会简单地传递给编译器,作为使用宏的替换文本。

C "Preprocessor" Macros Only Evaluate Constants and Other Macros

The short answer is a preprocessor expression only provides a meaningful evaluation of an expression composed of other preprocessor macros and constants.

Try this, you will not get an error:

#if sizeof < 2
int f(int x) { return x; }
#endif

If you generate assembly, you will find that sizeof < 2 compiles the function and sizeof >= 2 does not. Neither returns an error.

What's going on? It turns out that, except for preprocessor macros themselves, all identifiers in a preprocessor ("macro") expression are replaced with 0. So the above #if is the same as saying:

#if Easter_Bunny < 2

or

#if 0 < 2

This is why you don't actually get any sort of error when mistakenly using the sizeof operator in a preprocessor expression.

As it happens, sizeof is an operator, but it's also an identifier, and identifiers that are not themselves macros all turn into 0 in preprocessor expressions. The preprocessor runs, at least conceptually, before the compiler. It can turn non-C syntax into C so at the point it is running, the C program hasn't even been parsed yet. It isn't possible to reference actual C objects yet: they don't exist.

And naturally, a sizeof in the replacement text of a definition is simply passed through to the compiler as, well, the replacement text where the macro is used.

勿忘初心 2024-11-16 05:29:56

预处理器无法评估 sizeof 运算符的结果。这是在预处理器完成很久之后由编译器计算的。

由于第二个表达式导致编译时计算,因此它有效。第一个是对预处理器的不可能测试。

The preprocessor cannot evaluate the results of the sizeof operator. That is calculated by the compiler, long after the preprocessor is finished.

Since the second expression results in a compile-time computation, it works. The first is an impossible test for the preprocessor.

末骤雨初歇 2024-11-16 05:29:56

#define 只是文本替换。 #if 是一个条件预处理器指令,它会计算 sizeof(),但在预处理时,预处理器并不知道 sizeof() 是什么。预处理器在词法分析阶段之前运行。

#define is merely text replacement. #if being a conditional preprocessor directive evaluates sizeof() but at the time of preprocessing the preprocessor has no idea what sizeof() is. Preprocessor runs before the lexical analysis phase.

第几種人 2024-11-16 05:29:56

sizeof 在编译时被替换。
预处理在编译开始之前运行。

sizeof is replaced at compile time.
Preprocessing runs before compile starts.

帥小哥 2024-11-16 05:29:56

编译器不会触及任何一行。相反,预处理器会破坏文件,用宏替换任何 size(x) 实例。编译器确实看到了这些替换。

The compiler doesn't touch either line. Rather, the preprocessor rips through the file, replacing any instances of size(x) with your macro. The compiler DOES see these replacements.

天荒地未老 2024-11-16 05:29:56

预处理器不知道 sizeof 运算符,它只是无法理解它。所以#if 不起作用,因为它必须理解它才能工作,因为它是一个有条件的条件预处理器;它需要知道它的评估结果是 true 还是 false。

但是#define不需要理解sizeof,因为#define只是用于文本替换。预处理器在源代码中搜索 size 宏(在 #define 中定义),并将其替换为它定义的内容,即您的情况 sizeof( x)/sizeof(x[0])

Preprocessor doesn't know sizeof operator, it just cannot understand it. So #if doesn't work, since it has to understand it to work, because it is a conditional conditional preprocessor; it needs to know whether it evaluates to true or false.

But #define doesn't need to understand sizeof, as #define is just for text replacement. Preprocessor searches size macro (defined in #define) in the source code, and replaces it with what it is defined to be, which is in your case sizeof(x)/sizeof(x[0]).

浮萍、无处依 2024-11-16 05:29:56

它不起作用的原因是因为在代码到达编译器之前预处理器宏是在一次传递中“评估”的。因此,在 if 预处理器指令中,无法计算 sizeof(int) (实际上是 sizeof(int) != 4),因为这是由编译器而不是预处理器完成的。

不过,define 语句只是进行了文本替换,因此当涉及到编译器时,在任何有“size(x)”的地方,都会有“sizeof(x)/sizeof(x[0])”,然后这在编译阶段进行评估...在代码中具有“size(x)”的每个点

The reason it doesn't work is because the pre-processor macros are 'evaluated' in a pass before the code reaches the compiler. So in the if pre-processor directive, the sizeof(int) (actually the sizeof(int) != 4) cannot be evaluated because that is done by the compiler, not the pre-processor.

The define statement though, simply does a text substitution, and so when it comes to the compiler, everywhere you had 'size(x)' you would have 'sizeof(x)/sizeof(x[0])' instead, and then this evaluates there at the compile stage... at every point in the code where you had 'size(x)'

那一片橙海, 2024-11-16 05:29:56

如果您想检查处理器中整数的大小,请在运行预处理器之前使用 make 系统来发现系统上整数的大小,并将其写入头文件,例如 #define SIZEOF_INT 4,包含此头文件并执行 #if SIZEOF_INT == 4

例如,如果您使用 cmake,则可以使用 CMAKE_SIZEOF_INT 变量,该变量的大小为整数你可以放入一个宏。

If you want to check the size of the integer in the processor, use your make system to discover the size of integer on your system before running the preprocessor and write it to a header file as e.g. #define SIZEOF_INT 4, include this header file and do #if SIZEOF_INT == 4

For example, if you use cmake, you can use the CMAKE_SIZEOF_INT variable which has the size of the integer which you can put in a macro.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文