2013-04-01 26 views
6

Czy kompilatory C++ 11 (i czy nie) zauważają, że funkcja jest constexpr i traktować je jako takie, nawet jeśli nie są one zadeklarowane jako constexpr?niejawny constexpr?

byłem demonstrujący użycie constexpr komuś na przykładzie prosto z Wikipedii:

int get_five() {return 5;} 

int some_value[get_five() + 7]; // Create an array of 12 integers. Ill-formed C++ 

Ku mojemu zaskoczeniu kompilator było OK z nim. Więc dalej zmieniłem get_five(), aby wziąć kilka parametrów int, pomnożyć je i zwrócić wynik, nadal nie będąc jawnie deklarowanym jako constexpr. Kompilator też był w porządku. Wygląda na to, że jeśli kompilator może to zrobić, nie ma sensu posiadanie ograniczeń, które są wymagane, aby jawnie zadeklarować coś, co jest niemożliwe.

+4

Może twój kompilator obsługuje VLA jako rozszerzenie. Czy myślałeś o tym? – 0x499602D2

+1

Jaki to jest kompilator? – SomeWittyUsername

+0

możliwy duplikat [W książkach C++, tablica powiązana musi być stałym wyrażeniem, ale dlaczego poniższy kod działa?] (Http://stackoverflow.com/questions/5947661/in-c-books-array-bound-must-be -konstancyjno-ekspresyjny-ale-dlaczego-następujący-dorsz-kod) –

Odpowiedz

6

Na poprawnie działającym kompilatorze C++ 11 Twój kod zostałby odrzucony.

Na podstawie tego, że został zaakceptowany, prawie na pewno używasz gcc (lub czegoś, co dokładnie emuluje jego błędy). gcc [zależnie od flag] może przyjmować rozmiary tablic, które nie są stałe przez żadną miarę (np. zależą od danych wejściowych od użytkownika), ponieważ obsługują analog C99 o zmiennej długości w C++.

+0

'g ++' 4.6.3, 4.7.2 i 4.8 odrzucają to. Przynajmniej w wersji Liveworkspace: – SomeWittyUsername

+0

@icepack: Tak, wierzę, że możesz ją zabrać, aby odrzucić kod, który używa VLA, jeśli wybierzesz (ale domyślnie akceptuje VLA w C++). –

+1

@icepack Nie odrzuca go, gdy jest w funkcji: [LWS] (http://liveworkspace.org/code/1QPoBc$2) - ostrzega jednak! – us2012

1

Kompilator może wykryć, czy dana czynność mogła zostać zadeklarowana z constexpr nawet gdy nie mają, na optymalizacja celów (tj obliczania wyniku funkcji w czasie kompilacji). Kompilatory zrobiły to przed C++ 11.

Ale do użytku w miejscach, które wymagają stałych wyrażeń, takich jak parametry szablonu typu całkowego, niezgodne ze standardem jest umożliwienie wywoływania funkcji, które nie są zadeklarowane za pomocą słowa kluczowego constexpr.

+0

"__A kompilator może wykryć, czy dana funkcja mogła zostać zadeklarowana przy pomocy constexpr__" Czy masz jakieś odwołanie do tej kopii zapasowej? – cseder

+3

@cseder Trudno mi sobie wyobrazić, że żaden współczesny kompilator tego nie zrobiłby. Jest to podstawowa wiedza na temat działania kompilatorów. –

+0

To ledwo dowody.A kiedy mówisz "nowoczesne kompilatory", domyślam się, że wykluczyłeś najnowszy kompilator Visual C++ 2013, ponieważ nie obsługuje on automatycznej [memoizacji] (http://en.wikipedia.org/wiki/Memoization). Argument constexpr jest użyteczny tylko wtedy, gdy wynik zwracany przez funkcję constexpr jest taki sam za każdym razem i dlatego nie musi zawierać dużej wiedzy o kompilacji. – cseder