2010-10-11 96 views
2

一個朋友給我發了這個,我真的不知道它是什麼,在循環中。無論它是什麼調用std :: set構造函數五十萬次....任何幫助讚賞。我希望一個編譯器錯誤,但它實際上是在G ++ 4.4和4.5編譯和行爲是不同的拷貝構造...看不見的C++語法

#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

這是個問題嗎? – YeenFei 2010-10-11 07:10:03

+1

代碼不應該編譯。你有什麼問題? – GManNickG 2010-10-11 07:12:39

+0

在C++中使用 Abyx 2010-10-11 07:17:37

回答

12

您正在處理C++語言的GCC特定非標準擴展。每次迭代都定義了一個std::map對象的數組,並且立即銷燬它(i)。

在標準C++中,使用非常量表達式來指定數組大小是非法的,因此代碼不是合法的C++。它再次編譯只是因爲GCC允許它作爲擴展。

0

相同的代碼是

struct Foo {}; 

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

這是變量的聲明類型爲「Foo數組」的「地圖」;該數組具有動態大小i。

+3

這不應該在C++中編譯。有些編譯器可能會這樣做,但並不完全正確。 – JoshD 2010-10-11 07:17:22

+0

@Josh @GMan,除非它是由C++代碼中的GCC使用的C99 VLA。用'-pedantic'編譯給我'警告:ISO C++禁止變量數組'map''。 – 2010-10-11 07:18:52

0

在循環的迭代i中,您將創建一個i std :: sets數組。因此創建的總數爲i(i + 1)/ 2 = 500500.

+0

這就是它會做的,如果它編譯;) – Grozz 2010-10-11 07:21:25

+0

我猜他想知道他爲什麼有這麼多的構造函數調用。無論如何,爲我編譯的代碼基本上是相同的(g ++ 4.1.2 - 但我沒有提升,所以我使用了不同的typedef)。 – Kricket 2010-10-11 07:38:21

-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’ 
+0

我看到警告,沒有錯誤... – kay 2012-04-16 20:30:29

+1

true;但我總是用'-Werror'編譯來將警告視爲錯誤:-) – Arun 2012-04-21 03:35:47

1

AndreyT已經幾乎回答了這個問題,但這裏有一個更詳細的定義:

變長自動數組是 允許在ISO C99,並且作爲 擴展GCC在C90模式 和C++中接受它們。 (然而,GCC的 執行可變長度 陣列還沒有詳細 到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); 
} 

,則不應使用VLAS(在C++)ORalloca()(如海灣合作委員會的文件顯示,在http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html),因爲它們都被認爲相當 「咩」 的做法。它們都可能導致堆棧溢出和/或未定義的行爲。

編輯:更緊密地閱讀GCC文檔和看

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

..我認真希望像沒有人編寫代碼。我想這是一個很酷的功能,但仍然... wtf?