不,等等,忍受我...
VLA一直是GCC扩展,但它们被C99采用:
[C99: 6.7.5.2/4]:如果大小不存在,则数组类型是不完整类型.如果大小是*而不是表达式,则数组类型是未指定大小的可变长度数组类型,只能在具有函数原型范围的声明中使用; 尽管如此,这些数组仍然是完整类型.如果size是一个整型常量表达式,并且元素类型具有已知的常量大小, 则数组类型不是可变长度数组类型; 否则,数组类型是可变长度数组类型.
C99也称为ISO/IEC 9899:1999.
现在:
[C++11: 1.1/2]:C++是基于ISO/IEC 9899:1999(以下称为C标准)中规定的C编程语言的通用编程语言.除了C提供的功能之外,C++还提供其他数据类型,类,模板,异常,命名空间,运算符重载,函数名称重载,引用,免费存储管理操作符和其他库设施.
那么C++ 11也不应该有VLA吗?
似乎gcc对复杂的常量折叠有一些限制.这是一个例子:
static inline unsigned int DJBHash(const char *str)
{
int i;
unsigned int hash = 5381;
for(i = 0; i < strlen(str); i++)
{
hash = ((hash << 5) + hash) + str[i];
}
return hash;
}
int f(void)
{
return DJBHash("01234567890123456");
}
Run Code Online (Sandbox Code Playgroud)
当使用-O3优化级别(gcc 4.8)运行时,它很好地展开了DJBHash中的循环,并在编译期间计算该字符串的哈希值.
但是,当使字符串长一个字符时,return DJBHash("012345678901234567");它不再折叠它并生成带有条件跳转指令的循环.
我想将任意长度的文字字符串折叠为其哈希值作为编译时常量.
这可以吗?
我的问题是关于gcc的常量折叠优化(请参阅标题 - 请不要删除gcc和编译器标签)
这里的许多答案试图用模板或constexpr解决问题.很高兴知道这些选项,并感谢发布它们为所有人的利益.但是,他们没有直接回答我的问题.
实际上,我正在使用gcc端口,因此我可以根据需要更改和构建gcc源代码.但我只限于C,我想在这个范围内解决这个问题.
c compiler-construction gcc compiler-optimization constantfolding