有一个属性(gcc、clang、其他编译器)表明函数始终正常终止吗?

huangapple go评论70阅读模式
英文:

is there an attribute (gcc, clang, other compiler) that says a function always terminates normally?

问题

考虑以下C程序:

double local_array[10];
/* 本地计算 */
f(); // f()无法修改local_array,因为local_array尚未逃逸
local_array[i] += 5.0;

如果已知f()会正常返回,那么可以将local_array[i] += 5.0;移到调用前,可能是为了效率(可以将加载 - 浮点加法 - 存储序列与前面的计算混合在一起)。

但是,如果不知道f()是否会正常返回,这可能违反标准。确实,如果f()打印错误消息并退出,将其与对local_array[i]的访问前置可能是危险的(由于i的不正确值可能导致坏指针)。我们无法知道p指向有效且可写的内存。也许f()执行一个检查,排除p的无效值。

所以我的问题是:有没有办法告诉编译器(也许是gcc或clang)一个函数始终正常返回?

有一个nothrow属性,但似乎略有不同。

这样的属性将是noreturn的“双重”,意味着函数永远不会返回。

如果你想知道这是关于什么:PostgresSQL bug #616180是关于旧版本的gcc假定它们可以对函数调用前的陷阱指令进行类似的移动,该指令终止程序执行(由于检测到内部错误)。我认为gcc的做法是不正确的…但是如何告诉它允许执行这样的优化呢?

英文:

Consider the following C program:

double local_array[10];
/* local computations */
f(); // f() cannot modify the local_array since the local_array has not escaped
local_array[i] += 5.0;

If f() is known to return normally, then one can move local_array[i] += 5.0; before the call, perhaps for efficiency (one can intermingle the load - float add - store sequence with preceding computations).

However, if f() is not known to return normally, this is likely to be illegal with respect to the standard. Indeed, if f() prints an error message and exits, it would be dangerous to precede it with an access to local_array[i] that could fail (bad pointer due to an incorrect value of i). We have no way to know whether p points to valid, writable memory. Perhaps f() performs a check that excludes invalid values of p.

So my question: is there a way to tell the compiler (perhaps gcc or clang) that a function always returns normally?

There is a nothrow attribute but it seems slightly different.

Such an attribute would be the "dual" of noreturn, which means that a function never returns.

If you wonder what this is about: PostgresSQL bug #616180 was about old versions of gcc assuming they could make similar moves of a trapping instruction in front of a function call that terminated program execution (due to the detection of an internal error). I consider that what gcc was doing was incorrect… But then how would it be possible to tell it that it is allowed to perform such an optimization?

答案1

得分: 8

对于GCC:不,这样的属性不存在,甚至在编译器内部也没有(截至GCC 13)。

对于Clang/LLVM:LLVM IR具有willreturn函数属性,但Clang不会将其暴露给C和C++。

英文:

For GCC: no, such attribute does not exist, not even internally in the compiler (as of GCC 13).

For Clang/LLVM: LLVM IR has the willreturn function attribute, but Clang does not expose it for C and C++.

huangapple
  • 本文由 发表于 2023年4月17日 17:22:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76033584.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定