C++:优化无副作用的函数

标签 c++ optimization

在 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/

相关文章:

c++ - C语言中的const限定词和C++语言中的const限定词有什么区别?

c++ - 选择哪个数学库来转换 LabView 模块

python - Gekko 非线性优化,约束函数评估 if 语句时出现对象类型错误

php - (Laravel) 每次数据库发生变化时更新接口(interface)?

c++ - 设置为包含//在 Doxygen 中?

c++ - hash_map : why it defines less, 而不是 equal_to

带索引的mysql表优化

c# - 如何向 C# XmlDocument 添加新的根元素?

c++ - 如何减少 constexpr 函数的编译时间?

c++ - 如何处理库未提供的头文件