在 C++ 中有没有一种方法可以声明一个函数没有副作用?考虑:
LOG("message").SetCategory(GetCategory());
现在假设发布版本中的 LOG 宏创建了一个 NullLogEntry 对象,该对象将 SetCategory() 定义为一个空函数。所以基本上整个表达式可以(并且应该)被优化掉——除了理论上 GetCategory() 调用可能有一些副作用,所以我猜编译器不允许直接丢弃它。
另一个例子可能是忽略部分(或全部)参数的函数模板特化,但由于可能的副作用,不允许编译器在调用站点保存此类参数的评估。
我说的对吗?还是编译器可以优化掉这样的调用?如果不是,有没有办法提示编译器这个函数没有副作用,所以如果返回值被忽略那么整个调用就可以跳过?
最佳答案
这样做没有标准的方法,但是一些编译器有注释,你可以使用它来达到这种效果,例如,在 GCC 中,你可以在函数中使用 __attribute_pure__
标签(或者 __attribute__((pure))
) 告诉编译器该函数是纯(即没有副作用)。这在标准 C 库中广泛使用,例如:
char * str = get_some_string();
for ( int i = 0; i < strlen( str ); ++i ) {
str[i] = toupper(str[i]);
}
可以被编译器优化成:
char * str = get_some_string();
int __length = strlen( str );
for ( int i = 0; i < __length; ++ i ) {
str[i] = toupper(str[i]);
}
该函数在 string.h header 中声明为:
extern size_t strlen (__const char *__s)
__THROW __attribute_pure__ __nonnull ((1));
如果是 C++ 编译器解析函数,__THROW
是不抛出异常,而 __nonnull((1))
告诉编译器第一个参数不应为空(即,如果参数为空且使用 -Wnonnull 标志,则触发警告)。
关于C++:优化无副作用的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50496766/