看不见的C ++语法

时间:2010-10-11 07:01:24

标签: c++

一位朋友发给我这个,我真的不知道它是什么,在循环中。无论它是什么,它调用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;
};

5 个答案:

答案 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’