1

In C++, in some contexts, parentheses might change the meaning of the enclosed expression (for the given context). For example, decltype(expr) and decltype((expr)) often yeld different types:

int x;
decltype(x) a=x; // type int; a initialized with a copy of x
decltype((x)) b=x;//type int&; b is a reference to  x; extra parentheses matter!

But what about C?

Enclosing macro parameters into parentheses is a common practice in C, can that produce some unexpected side effects?

[edit ]More precisely, if the parentheses are redundant for grouping, may they change program meaning?

I consider only expressions (not other syntactic elements such types, functions parameters lists, etc).

4

3 回答 3

1

我相信答案是“不”。

我不知道在任何情况下添加一对额外的不必要的括号((blah))会改变含义。正如您所说,这对于大多数宏定义至关重要。

但是,在各种情况下,显式分组会导致与数学规则无关的变化。我不是指(1+2)*3;那只是数学。我的意思是编译器最终会产生一个不同但等效的代码序列,它的效率更高,或者可能更低。

例如,考虑这个函数;

float fourth_power (float n) {
  return n*n*n*n;
}

它可以与此功能不同地执行:

float fourth_power (float n) {
  return (n*n)*(n*n);
}

在纯数学中,结果应该是相同的,但实际上对于有限大小的浮点值,您可以获得不同的数字答案,但这不是我在这里谈论的内容。

我所说的变化是第二种形式运行得更快。如果您知道您只使用较小的数字(浮动的限制不是问题),那么您可能希望以第二种方式对其进行编码以提高速度。

事实上,如果你使用 GCC -ffast-math,我认为 GCC 会进行这种转换,但通常编译器会安全地进行。

这是一个可能适用于所有编译器的示例(因为它与数值准确性有关),但是在许多示例中,明显任意的分组决策可以使特定编译器走上不同的内部决策路径,并且可以产生有趣且可衡量的性能、代码大小等方面的差异。

于 2013-10-30T12:06:09.927 回答
0

像这样的东西?

#define ODD( n ) n % 2

int a = 2;
bool n1 = ODD( a + 1 ); // a + 2 % 2
bool n2 = ODD( (a+1) ); // (a + 2) % 2

n1 true (!=0)
n2 false (==0)
于 2013-10-30T13:07:50.637 回答
0

也许你的意思是这样的:

#define SIMPLE_USELESS_MACRO(X) (X)

int int_ = 2;
long int long_int_ = 2L;
double double_ = 3.14;

double result = long_int_ + SIMPLE_USELESS_MACRO(int_ + double_);

如果我是对的,如果括号在 x 附近,则转换顺序如下:

(假设没有编译器优化)

1) int -> double 2) long int -> double

如果没有括号,则转换顺序为:

1) int -> long int 2) long int -> double

我不确定上述转换的时间,但整数->浮点转换可能需要更多时间(假设没有硬件单元对此负责)。

这只是一个建议,如果我错了对不起。

于 2013-10-30T12:18:30.043 回答