wes*_*ton 48 c parentheses c-preprocessor
显然,有些时候#defines必须有括号,如下:
#define WIDTH 80+20
int a = WIDTH * 2; // expect a==200 but a==120
Run Code Online (Sandbox Code Playgroud)
所以我总是括号,即使它只是一个数字:
#define WIDTH (100)
Run Code Online (Sandbox Code Playgroud)
C的新人问我为什么这样做,所以我试图找到一个边缘情况,在一个数字上没有括号#define会导致问题,但我想不出一个.
这种情况是否存在?
Ale*_*ler 38
是的.预处理器连接operator(##)将导致问题,例如:
#define _add_penguin(a) penguin ## a
#define add_penguin(a) _add_penguin(a)
#define WIDTH (100)
#define HEIGHT 200
add_penguin(HEIGHT) // expands to penguin200
add_penguin(WIDTH) // error, cannot concatenate penguin and (100)
Run Code Online (Sandbox Code Playgroud)
对于stringization(#)也是如此.很明显,这是一个极端情况,考虑到WIDTH可能会如何使用可能无关紧要.尽管如此,仍需要牢记预处理器.
(为什么加入第二企鹅失败的原因是在C99预处理规则微妙的细部- IIRC它失败,因为串联到两个非占位符的预处理标记必须始终导致单个预处理标记-但这是无关紧要的,即使级联被允许它仍会给出与未被括号内的不同的结果#define!).
所有其他响应都是正确的,只要从C++扫描器的角度来看无关紧要,因为实际上,数字是原子的.但是,在我阅读这个问题时,没有任何迹象表明只考虑没有进一步预处理器扩展的情况,所以其他答案即使我完全同意其中包含的建议也是错误的.
asv*_*kau 27
有时您必须编写代码而不是考虑当前的警告,但是下次将要编辑的警告 .
现在你的宏是一个整数.想象一下将来有人编辑它.让我们说他们不是你,而是一个不那么小心或更匆忙的人.括号用于提醒他们在括号中进行任何修改.
这种想法在C中是一个好习惯.我个人以一种人们可能会发现"冗余"的方式编写代码,这类似的东西,尤其是错误处理方面.冗余用于将来编辑的可维护性和可组合性.
正如Blagovest Buyukliev所说:
define由单个标记(仅一个操作数,无操作符)组成,不需要括号,因为单个标记(例如100)在进行lexing和解析时是不可分割的原子.
但是在宏方面我会推荐以下规则:
如果你想使用像宏这样的函数严重考虑以下2条规则:
为什么要统治1?(保持操作顺序正确)
#define quad(x) (x*x)
int a = quad(2+3);
Run Code Online (Sandbox Code Playgroud)
将扩展到:
int a = (2+3*2+3);
Run Code Online (Sandbox Code Playgroud)
为什么要统治2?(确保副作用仅应用一次)
#define quad(x) (x*x)
int i = 1;
int a = quad(i++);
Run Code Online (Sandbox Code Playgroud)
将扩展到:
int a = i++ * i++;
Run Code Online (Sandbox Code Playgroud)
没有.没有任何案例#define WIDTH 100可以产生明确或"令人惊讶"的扩张.那是因为它只能导致单个令牌被单个令牌替换.
如您所知,当单个令牌(例如WIDTH)导致多个令牌(例如80 + 20)时,会出现宏观混淆.据我所知,这是在替换中使用括号的唯一原因,正如我在第一段中所探讨的那样,它不适用于此.
但是,抛开这个技术事实,它仍然是一个很好的做法.它可以促进习惯,如果宏被修改为更复杂的东西,它也可以作为提醒.
当代码只定义一个数字时,@ Alexander Gessler很好地回答了这个问题。
但是,许多编码人员在以下情况中并未注意到一元运算符:
#define TEMPERATURE1M (-1)
#define TEMPERATURE1P (+1)
Run Code Online (Sandbox Code Playgroud)
当代码使用使用#define运算符的a时,封闭可()确保预期的数值结果和优先级。
#define TEMPERATURE_WITH (-1)
#define TEMPERATURE_WITHOUT -1
// Consider how these will compile
int w = 10-TEMPERATURE_WITH;
int wo = 10-TEMPERATURE_WITHOUT; // May not compile
Run Code Online (Sandbox Code Playgroud)
给定C99语义更改@Olaf,最后一行代码可以编译
| 归档时间: |
|
| 查看次数: |
17466 次 |
| 最近记录: |