一位朋友发给我这个,我真的不知道它是什么,在循环中。无论它是什么,它调用std :: set构造函数五十万次....任何帮助表示赞赏。我希望编译器出错,但实际上它在g ++ 4.4和4.5中编译,并且行为与复制构造不同......
#include <stdio.h>
#include <stdlib.h>
#include <boost/unordered_map.hpp>
#include <set>
#include <string>
typedef boost::unordered_map<int, std::set<int> > mymap;
int main () {
mymap map;
for ( int i = 0 ; i < 1000 ; i++ )
{
std::set<int> map[i] ;
}
return 1;
};
答案 0 :(得分:12)
您正在处理GCC特定的C ++语言非标准扩展。每次迭代都定义了一个带有std::map
元素的i
个对象数组(并立即销毁它)。
在标准C ++中,使用非常量表达式指定数组大小是非法的,因此代码不是合法的C ++。它再次编译,只是因为GCC允许它作为扩展。
答案 1 :(得分:1)
AndreyT几乎已经回答了这个问题,但这里有一个更详细的定义:
可变长度自动数组 允许在ISO C99中,并作为 扩展GCC在C90模式下接受它们 在C ++中。 (但是,海湾合作委员会的 可变长度的实现 数组还没有详细说明 符合ISO C99标准。)这些数组 宣称像任何其他自动 数组,但长度不是 一个恒定的表达。存储是 在声明点分配 并且在支撑级别时释放 退出了。例如:
FILE *
concat_fopen (char *s1, char *s2, char *mode)
{
char str[strlen (s1) + strlen (s2) + 1];
strcpy (str, s1);
strcat (str, s2);
return fopen (str, mode);
}
你不应该使用VLA(在C ++中) OR alloca()
(正如GCC文档在http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html所建议的那样),因为它们都被认为是非常“meh”的做法。它们都可能导致堆栈溢出和/或未定义的行为。
编辑:更仔细地阅读GCC文档并查看
int tester (int len, char data[len][len])
{
/* ... */
}
..我真的希望没有人写这样的代码。我想这是一个很酷的功能,但仍然...... wtf?
答案 2 :(得分:0)
相同的代码是
struct Foo {};
int main()
{
int i = 100;
Foo map[i];
}
这是“foo数组”类型的变量“map”的声明;该数组具有动态大小i。
答案 3 :(得分:0)
在循环的迭代i中,您创建了一个i std :: sets数组。因此,创建的总数是i(i + 1)/ 2 = 500500。
答案 4 :(得分:-1)
我看到以下编译错误
alias g++
alias g++='g++ -ansi -pedantic -Wall -W -Wconversion -Wshadow -Wcast-qual -Wwrite-strings'
c.cpp: In function ‘int main()’:
c.cpp:10: warning: ISO C++ forbids variable length array ‘map’
c.cpp:10: warning: declaration of ‘map’ shadows a previous local
c.cpp:7: warning: shadowed declaration is here
c.cpp:10: warning: unused variable ‘map’