2014-09-25 20 views
8
typedef int (*A)[3]; 

int (**p)[3] = new A;    // OK 
int (**q)[3] = new (int(*)[3]); // OK 
int (**r)[3] = new int (*)[3];  // error 

Błąd z GCC to error: expected primary-expression before ')' token. Dlaczego dodatkowe nawiasy są wymagane w tym wyrażeniu?Dlaczego nowy int (*) [3] jest błędem?

+0

pokrewne (ale nie powielać): http://stackoverflow.com/q/16634713/1505939 –

+1

Ponieważ * Nowy typ-id * może nie zawierają nawiasów. Ale to oczywiście nie jest satysfakcjonująca odpowiedź. – dyp

+0

Może to ma związek z ujednoznacznieniem; na przykład 'new int()' może być interpretowane jako próbujące przydzielić funkcję 'int (void)' – dyp

Odpowiedz

10

Standard definiuje nowy typ ID jako najdłuższą sekwencję nowych deklaratorów . Jest też notatka, która ilustruje podobną sytuację (chociaż przyznaje wskaźniki do funkcji):

5.3.4 Nowy [expr.new]

....

Nowy typ ID:
        typu specyfikator-nastnowych declaratoropcjonalnie

nowych declarator:
        PTR-operator nowej declaratoropcjonalnie
        noptr-nowego declarator

noptr-nowego declarator:
        [  ekspresji  ]   atrybut specyfikator-nastopcjonalnie
        noptr-nowego declarator  [  stałej ekspresji  ]   atrybut specyfikator-nast opcjonalnie

....

nowego typu ID w nowy- wyrażenie jest najdłuższą z możliwych sekwencji nowych deklaratorów. [ Uwaga: to zapobiega niejednoznaczności między operatorami declarator &, &&, * i [] i ich odpowiedniki ekspresji.-   koniec uwaga] [Przykład:

new int * i; // syntax error: parsed as (new int*) i, not as (new int)*i 

* jest declarator wskaźnik i nie operator mnożenia. -   przykład koniec]

[Uwaga: nawiasach w nowego typu ID z nowej ekspresji może mają zaskakujące efekty. [Przykład:

new int(*[10])(); // error 

jest źle ukształtowany, ponieważ wiązanie jest

(new int) (*[10])(); // error 

Zamiast jawnie nawiasach wersja operatora new mogą być wykorzystywane do tworzenia przedmiotów typów związków (3.9. 2):

new (int (*[10])()); 

przydziela tablicę 10 wskaźników do funkcji (bez żadnego argumentu) i powracając: int. -   koniec przykład] -   koniec uwaga]

+0

@MattMcNabb Jak zwykle, w standardzie jest to nieco trudne. Dodałem trochę konstrukcji gramatycznych, ale nie są one kompletne. Na przykład. rzeczy takie jak _expression_ lub _attribute-specifier-seq_ nie są tutaj zdefiniowane. – AlexD

+0

Wyrażenie @AlexD * byłoby zbyt skomplikowane, a * atrybut-specifier-seq * jest nieistotny. IMHO, interesującą częścią jest to, że * nowe wyrażenie * może zawierać albo (całkowicie) parentessizowany * id-type * albo (n-unparenthesized) * nowy-typ-id *, gdzie * nowy-typ-id * może (o ile widzę) nie zawierać nawiasów. – dyp

+0

@dyp Z tego, co rozumiem, _new_type_id_ może zawierać _expression_, który może zawierać nawiasy, np. 'new int [(3)]'. BTW, dzięki za edycję pierwszego posta! – AlexD

Powiązane problemy