4

我正在用 C 编写一个非破坏性转换例程,我刚刚意识到(至少在 Visual C++ 中)函数是以相反的顺序解析的。

所以:

main()
{
char* psString[] = { "Hello", "World", "World2", "World3" };

printf("%s - %s - %s - %s\n", 
    H2A_N(psString[0]), 
    H2A_N(psString[1]), 
    H2A_N(psString[2]), 
    H2A_0(psString[3]));

return 1;  
};

我的代码不是可重入的,只在一个线程中运行,所以我打算使用一个静态字符数组来存储结果。

我的计划是有一个函数 H2A_0,它将输出写入缓冲区的开头并留下下一个地址以供后续调用 H2A_N。

我确实意识到这种方法存在一些缺点,但我必须将此转换例程应用于许多现有代码,因此越简单越好(我不想弄乱释放内存)。

我的问题是:

  1. 以相反的顺序解析函数(当它们作为参数传递给其他函数时)是否是 C 标准的一部分。
  2. 有一个更好的方法吗?
4

3 回答 3

7

没有定义的参数评估顺序。编译器可以随意决定评估它们的顺序。

最新版本的标准 C11 是这样说的,§6.5.2.2/10:

在函数指示符和实际参数的评估之后但在实际调用之前有一个序列点。调用函数中的每个求值(包括其他函数调用)在被调用函数的主体执行之前或之后没有特别排序的,相对于被调用函数的执行是不确定的。

如果您希望强制执行特定的评估顺序,您需要将表达式从函数调用中提取出来,并将它们保存到局部变量中。

int param1 = foo(...);
int param2 = bar(...);
DoSomething(param1, param2);

有一个更好的方法吗?

很可能。让函数返回值并将副作用应用于固定长度的静态分配缓冲区通常不被认为是最佳实践。但是,我不想告诉你如何解决你的问题,因为我对这个问题了解不够。

于 2013-06-01T21:24:07.153 回答
1

以相反的顺序解析函数(当它们作为参数传递给其他函数时)是否是 C 标准的一部分。

函数参数被评估为表达式;因此,它是实现定义的,就像在x = f() + g(). 如果f()将在g()依赖于编译器到编译器之前调用,请检查序列点

一些编译器,比如icc可以给出警告:

备注 #981: 操作数以未指定的顺序计算

于 2013-06-01T21:53:01.997 回答
-2

应该先检查。没有明确的解决顺序。大多数编译器似乎从右到左解析。

于 2013-06-01T21:37:14.133 回答