Pytanie W języku C ++ czy zakres nazwanego parametru zawiera wyrażenie dla jego wartości domyślnej?


Przykład: Czy to legalne C ++ 14?

#include <iostream>
static int d() {
    return 42;
}
static int e(int d = d()) {
    return d;
}
int main() {
    std::cout << e() << " " << e(-1) << std::endl;
}

g ++ 5.4 z -std=c++14 lubi to, ale clang ++ 3.8 z -std=c++14 narzeka:

samename.cxx:3:23: error: called object type 'int' is not a function or function pointer
static int e(int d = d()) {return d;}
                     ~^

21
2018-02-17 11:11


pochodzenie


również powtarzalne z językiem 3.9.1 melpon.org/wandbox/permlink/8RCXqcgCZzbN7l5o - user1810087
Może duplikat stackoverflow.com/questions/334882/... - Ashwani Dausodia
Mój zdrowy rozsądek mówi mi, że klang jest w tej sytuacji słuszny, ponieważ d parametr cienie d funkcja globalna. Nie cytuj mnie jednak na ten temat. - DeiDei
Myślę, że @DeiDei ma rację: static int e(int d = ::d()) {return d;} kompiluje. widzieć tutaj - user1810087
Kiedyś uważałem te pytania za interesujące, ale teraz moją pierwszą reakcją jest ... kogo to obchodzi? Taki kod i tak nie przejdzie przeglądu. Wybierz lepszą nazwę dla swoich zmiennych i funkcji. - Lightness Races in Orbit


Odpowiedzi:


Od basic.scope.pdecl / 1:

Punkt deklaracji nazwy jest natychmiast po jej zakończeniu   deklarator i przed inicjatorem (jeśli taki istnieje), z wyjątkiem przypadków wymienionych poniżej.

Przykład:

unsigned char x = 12;
{ unsigned char x = x; }

Tutaj drugi x jest inicjowana z własną (nieokreśloną) wartością.

Clang jest zgodny z tą sekcją normy. Wydaje się, że GCC tylko to stosuje {block}.

Dany:

constexpr int d() {return 42;}

Następujące nieudane w Clang, ale działa w GCC:

static int e(int d = d()) {return d;}
             // This ^^d should refer to the new name that shadows ::d()

Następujące błędy nie udają się zarówno w Clang i GCC:

void func(){
    int d = d();
         // ^^d here refers to the new name that shadowed ::d();
 }

16
2018-02-17 11:28



Czy na pewno dotyczy to domyślnych argumentów? Istnieje kilka sposobów, w jakie różnią się one od standardowych inicjalizacji torfowisk. Zasadniczo: czy to naprawdę inicjator? - Lightness Races in Orbit
@LightnessRacesinOrbit, "czy to naprawdę inicjator?" - Zgodnie z to, Powiem tak, jest. - WhiZTiM
Okay, tak, wygląda dobrze :) - Lightness Races in Orbit


Wygląda na to, że nie jest legalne: zobacz specyfikację C ++ 14 (sekcja 3.3.2 - Punkt deklaracji).

int x = 5;
{ int x = x; } // second x is initialized with its own undetermined state
{ int x[x]; }  // declares an array with 5 elements, since the declaration of 
               // second x is not complete when the first x is used

W twoim przypadku deklaracja d jest kompletny, więc kiedy używasz d() odnosisz się do zmiennej, a nie do funkcji.


11
2018-02-17 11:23