2012-03-20 14 views
5

Quando chiamo NSLog da C++, Xcode si lamenta che la stringa di formato passata a NSLog non è una stringa letterale. Ecco una riga di codice che fa scattare l'allarme:Chiamare NSLog da C++: "La stringa di formato non è una stringa letterale (potenzialmente insicura)"

NSLog(CFSTR("Leaking?")); 

Io non sono a conoscenza di un modo per codificare un NSString letterale in C++, e non vedo un avvertimento relativo posso spegnere nelle impostazioni del progetto . C'è un modo per chiamare NSLog da C++ senza attivare questo messaggio? Sto usando Xcode 4.2.1.

Modifica: Questo è veramente il codice C++. Di solito evito Objective-C++, attenendomi a Objective-C o al vecchio C++, perché non c'è documentazione ufficiale su cosa funzioni in Objective-C++ e cosa no. Ho trovato solo vaghi avvertimenti che (per esempio) potrebbero esserci problemi con alcune parti del STL. Uso modelli, STL e altre funzionalità "avanzate" di C++, quindi voglio giocare sul sicuro.

Modifica n. 2, la soluzione: ho appena capito che clang supporta un numero molto maggiore di flag di avviso rispetto a quelli effettivamente documentati. (Dovrebbe essere ovvio dalla lunga lista di avvertimenti che Xcode mi ha offerto.) Ho provato -Wno-format-nonliteral a la gcc, e ora Xcode è felice.

+2

Se si chiama 'NSLog', che fa parte di Foundation, si utilizza Objective-C. Usa '@" Leaking? "' E assicurati che il tuo file abbia un'estensione '.mm'. – Joe

+0

@Joe ... a meno che non intenda Objective-C++? – csl

+1

@csl Ho spostato il commento a una risposta con qualche chiarimento. – Joe

risposta

7

Tutto ciò che dovete fare è scrivere @"this" per creare un oggetto NSString letterale.

Quindi sostituire quella linea con NSLog(@"Leaking?"); e si dovrebbe andare bene.

Potrebbe essere necessario rinominare il file con l'estensione .mm per assicurarsi che sia compilato come Objective-C++ (il figlio di amore mutante di Objective-C e C++). Se non si desidera farlo, è possibile creare una funzione wrapper in un file minuscolo che chiama NSLog e quindi chiamare tale funzione dal codice C++. Si sarebbe simile a questa:

void MyNSLog(const char *message) 
{ 
    NSLog(@"%s", message); 
} 

Nota che il motivo per il compilatore ti dà dolore è che l'utilizzo di tutto tranne che una stringa immutabile letterale (dove i contenuti sono noti al momento della compilazione) è un rischio per la sicurezza. In caso contrario, la stringa di formato potrebbe essere modificata in modo da includere gli specificatori di formato (ad es., %d) per i parametri che non sono presenti. Se ciò accadesse, NSLog otterrebbe solo puntatori casuali dallo stack e potrebbe accadere qualcosa di brutto. (Vedere this question per ulteriori informazioni.)

+0

+1 per la risposta aggiornata. – Joe

+0

+1 per il suggerimento di definire una funzione di supporto in un file .mm separato. Questa volta non l'ho usato, ma sono sicuro che tornerà utile in futuro, dato che sono generalmente cauto nell'utilizzare Objective-C++. – dkh

4

Se si sta chiamando NSLog, che è parte di Foundation, si utilizza Objective-C. Usa NSLog(@"Leaking?"); e assicurati che il tuo file abbia l'estensione .mm per chiarire che stai mixando Objective-C e C++.

+0

Giusto per chiarire, sono confuso. Perché non nominare semplicemente un'estensione '.m' invece di' .mm', se Foundation è Objective-C? Volevi dire che NSLog è Objective C++, o sono confuso? Grazie! – jmort253

+1

Stavo ipotizzando che forse 'NSLog' veniva chiamato da un file' .cpp' che non funzionava perché 'NSLog' è solo' Objective-C'. E per mixare 'Objective-C' e' C++ 'l'estensione [dovrebbe essere' .mm'] (http://stackoverflow.com/questions/7727249/calling-c-function-from-objective-c-class/7727308 # 7.727.308). – Joe

Problemi correlati