C++ 看不见的C++;语法

C++ 看不见的C++;语法,c++,C++,一个朋友寄给我这个,我真的不知道它是什么,在循环中。不管它调用std::set构造函数的次数是多少,都有50万次。。。。谢谢你的帮助。我预计会出现编译器错误,但它实际上是在g++4.4和4.5中编译的,其行为与复制构造不同 #include <stdio.h> #include <stdlib.h> #include <boost/unordered_map.hpp> #include <set> #include <string>

一个朋友寄给我这个,我真的不知道它是什么,在循环中。不管它调用std::set构造函数的次数是多少,都有50万次。。。。谢谢你的帮助。我预计会出现编译器错误,但它实际上是在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;
};
#包括
#包括
#包括
#包括
#包括
typedef boost::无序的_-map-mymap;
int main(){
我的地图;
对于(int i=0;i<1000;i++)
{
std::集映射[i];
}
返回1;
};
相同的代码是

struct Foo {};

int main()
{
    int i = 100;
    Foo  map[i];
}

它是“Foo数组”类型的变量“map”的声明;这个数组有一个动态大小i。

在循环的迭代i中,您创建一个i std::set数组。创建的总数是i(i + 1)/2=500500。< /p> < p>您正在处理GCC专用的非标准扩展C++语言。每次迭代都使用
i
元素定义一个
std::map
对象数组(并立即销毁它)


标准C++中使用非常量表达式指定数组大小是非法的,因此代码不是合法的C++。它再次编译,只是因为GCC允许它作为扩展。

我看到以下编译错误

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’

AndreyT已经回答了这个问题,但这里有一个更详细的定义:

可变长度的自动数组是 ISO C99中允许,并且作为 扩展GCC在C90模式下接受它们 在C++中。(但是,GCC的 可变长度的实现 数组在细节上还不一致 符合ISO C99标准。)这些阵列 与任何其他自动类型一样声明 数组,但长度不是 不变的表达式。储藏室是 在申报时分配 并在支架水平时取消分配 退出。例如:

您不应该使用VLAs(在C++)
alloca()
(正如GCC文档在中所建议的那样),因为它们都被认为是相当“meh”的实践。它们都可能导致堆栈溢出和/或未定义的行为

编辑:更仔细地阅读GCC文档并查看

 int tester (int len, char data[len][len])
 {
   /* ... */
 }

。。我真的希望没有人写这样的代码。我想这是一个很酷的功能,但仍然。。。wtf?

代码甚至不应该编译。你的问题是什么?在C++中使用,它是一个GCC扩展,允许在C++中使用可变长度数组(VLAS)(它是C99的标准特性)。C++不应该编译它。有些编译器可能会这样做,但它并不完全正确。@ Juh @ Gman,除非它是GCC在C++代码中使用的C99 VLAS。用<代码> -PodiANTIC/<代码>编译:我给出了代码>警告:ISO C++禁止可变长度数组“map”< /> >。我猜他想知道为什么他有这么多构造函数调用。无论如何,基本上做相同事情的代码为我编译(g++4.1.2-但我没有boost,所以我使用了不同的typedef);但我总是使用
-Werror
编译,将警告视为错误:-)
 int tester (int len, char data[len][len])
 {
   /* ... */
 }