2014-12-29 11 views
7

Secondo l'esempio, che la standard fornisce al N4296::13.3.3 [over.match.best]Perché non è compilatore errore di tempo gettati quando chiamiamo a una funzione C

namespace A 
{ 
    extern "C" void f(int = 5); 
} 

namespace B 
{ 
    extern "C" void f(int = 5); 
} 

using A::f; 
using B::f; 

void use() 
{ 
    f(3); // OK, default argument was not used for viability 
    f(); // Error: found default argument twice 
} 

come standard dice a N4296::7.5/6 [dcl.link]:

due dichiarazioni per una funzione con collegamento di linguaggio C con lo stesso nome di funzione (ignorando i nomi di spazi dei nomi che lo qualificano) che vengono visualizzati in ambiti di spazio dei nomi diversi, fare riferimento alla stessa funzione.

ho cercato di scoprire una cosa del genere da solo esempio:

#include <iostream> 

namespace A 
{ 
    extern "C" void foo(int a = 5){ std::cout << a << "1" << std::endl; } 
} 

namespace B 
{ 
    extern "C" void foo(int a = 5); 
} 

using A::foo; 
using B::foo; 

int main() 
{ 
    foo(); //Error 
    foo(2); 
} 

DEMO

Allora perché il mio esempio funziona? Quali sono le differenze tra il mio esempio e l'esempio dello standard a meno che non abbia definito esplicitamente la funzione nello spazio dei nomi A? Perché questo è così importante?

+0

Sono solo curioso di sapere qual è il significato di una funzione "extern" C "' all'interno di uno spazio dei nomi C++. –

+0

Ri: "Quali sono le differenze tra il mio esempio e l'esempio dello standard a meno che non definissi esplicitamente la funzione nello spazio dei nomi A?": Ho appena provato a modificare la tua demo in * not * definire esplicitamente la funzione, e comunque è stata compilata correttamente. (Collegamento fallito, ovviamente.) Quindi questa non è la differenza. Sembra che g ++ semplicemente non dia un errore in questa situazione. – ruakh

+0

[Clang accetta anche questo] (http://coliru.stacked-crooked.com/a/2c544e25d8dcdac8). Hmm ... Btw, una parte importante della specifica mancante dalla tua domanda: * "Se la migliore funzione valida si risolve in una funzione per la quale sono state trovate più dichiarazioni, e se almeno due di queste dichiarazioni - o le dichiarazioni a cui si riferiscono nel caso di using-dichiarazioni - specificare un argomento predefinito che ha reso la funzione valida, il programma è mal formato. "* Sembra un difetto di Clang e g ++? – cdhowie

risposta

1

Come già osservato nei commenti, non vi è alcuna differenza rilevante tra l'esempio dello standard e l'esempio. I compilatori che implementano correttamente il problema standard sono una diagnostica per entrambi.

Il fatto che questo è chiaramente un bug del compilatore in almeno clang e Intel può essere visto quando si modifica l'esempio al insensato

namespace A 
{ 
    extern "C" void f(int = 5); 
} 

namespace B 
{ 
    extern "C" void f(int = 3); // different default argument 
} 

using A::f; 
using B::f; 

void use() 
{ 
    f(); // No error ! 
} 

Nonostante ottenendo due diversi argomenti di default, nessun errore o anche viene generato un avviso. Viene utilizzato uno degli argomenti predefiniti, il primo con Intel, il secondo con clang.

GCC rifiuta questo esempio insensato, quindi non c'è un modo semplice e veloce per verificare che sia chiaramente un bug in GCC, ma ciò non cambia il fatto che lo sia: come notato, accetta silenziosamente l'esempio dallo standard in cui lo standard indica dove deve essere rilevato un errore.

Problemi correlati