2009-10-29 21 views
5

NOTA BENE: Non ho fatto C++ per qualche tempo ...C/C++ funzione/metodo di decorazione

E 'comune al giorno d'oggi per decorare dichiarazioni di metodo C/C++/funzione al fine di migliorare la leggibilità?

grezzo Esempio:

void some_function(IN int param1, OUT char **param2);

con le macro IN e OUT definiti con un vuoto corpo (cioè documentazione leggero se si vuole in questo esempio). Naturalmente capisco che questo va in qualche modo in parallelo con il "blocco commento doc" associato al metodo/funzione.

Potrebbe fornire qualche altro esempio ... assumendo che questo argomento sia utile per la comunità. Si prega di tenere presente che l'esempio sopra è proprio quello che è.

+8

Penso che sia meglio contrassegnare * gli IN con la parola chiave 'const'. –

+6

Yuck! Fare in modo che i futuri manutentori cerchino una macro inutile invece di inserire queste informazioni in un commento? Rischiare interferenze con altri macro esistenti? No grazie! – ctd

+0

@Nick D, a volte si desidera utilizzare il passaggio non const del valore per i parametri IN come una piccola ottimizzazione 'type f (tipo value) {value.op(); valore di ritorno; } 'Ciò consente al compilatore di elidere non solo la copia del valore di ritorno ma anche la creazione di copie di input se l'argomento passato è temporaneo. –

risposta

17

Non apprezzerei tale decorazione.

molto meglio utilizzare const e referenze e riferimenti costanti, come in

void some_function(AClass const &param1, AnotherClass &param2) 

solito int sono passati per valore e non per riferimento, così ho usato AClass e AnotherClass per l'esempio. Mi sembra che aggiungere empy IN e OUT sarebbe fonte di distrazione.

0

Non l'ho mai visto prima. Penserei che sarebbe meglio inserire informazioni come questa nei commenti.

1

cerco di usare:

  • valori per i parametri di input o riferimenti se sono grandi
  • Riferimenti per parametri out
  • Puntatori per dare la proprietà alla funzione chiamata

Most del tempo è davvero facile vedere quali sono i parametri IN o OUT, ovviamente i nomi propri nella dichiarazione sono una buona documentazione.

Trovo fastidiosi quelli di IN, OUT.

2

Non in C++, non ho fatto di programmazione C professionalmente ma almeno in C++ il tipo dei parametri è auto-esplicativo:

void f(std::string const &); // input parameter 
void f(std::string);   // input parameter again (by value) 
void f(std::string&);  // in/out parameter 
std::string f();    // output 

Che insieme a codice documentare strumenti (Doxygen) dove si aggiungere un contesto ai parametri (quali valori sono previsti o non accettabili dalla funzione, come la funzione cambia gli oggetti passati ...

Informazioni sui puntatori: Tendiamo a limitare i puntatori grezzi nelle nostre interfacce di metodo. possono essere usati, ma in generale si dovrebbero preferire i puntatori intelligenti, poi di nuovo la semantica della proprietà viene dalla choic e del puntatore intelligente: shared_ptr <> per la responsabilità condivisa diluita (o quando necessario), auto_ptr <>/unique_ptr <> per proprietà singola (solitamente come valore di ritorno da fabbriche, locali o attributi membro) ...

+0

'T &' può essere sia "out" che "in/out", però. –

+0

Sì, ma deve essere un oggetto completamente costruito, quindi non è "puramente" fuori. Io tendo a vederli (questo è solo me, non un terreno comune) come parametri in/out indipendentemente dal fatto che siano elaborati/letti all'interno. Sebbene accettabile, richiederei una spiegazione per un argomento ricevuto per riferimento il cui valore non è utilizzato all'interno della funzione in una revisione del codice. Luoghi in cui è accettabile: una funzione che restituisce un buffer raw (puntatore a un blocco di memoria) che aggiorna anche la dimensione passata come parametro (solo * dopo * hanno * veramente * giustificato non utilizzando un costrutto più sicuro) o come ottimizzazione, se necessario –

1

ho visto questo, ma non credo che direi che è "comune".

L'API Win32 (non c C++) utilizza qualcosa di simile:

WINADVAPI 
BOOL 
WINAPI 
CreateProcessWithLogonW(
    __in  LPCWSTR lpUsername, 
    __in_opt LPCWSTR lpDomain, 
    __in  LPCWSTR lpPassword, 
    __in  DWORD dwLogonFlags, 
    __in_opt LPCWSTR lpApplicationName, 
    __inout_opt LPWSTR lpCommandLine, 
    __in  DWORD dwCreationFlags, 
    __in_opt LPVOID lpEnvironment, 
    __in_opt LPCWSTR lpCurrentDirectory, 
    __in  LPSTARTUPINFOW lpStartupInfo, 
    __out  LPPROCESS_INFORMATION lpProcessInformation 
    ); 

Nel caso del Visual C++ 2005 e versioni successive compilatori, questi realmente mappa a dichiarazioni come __$allowed_on_parameter e vengono controllati al momento della compilazione.

7

intestazioni di Windows in realtà fanno esattamente questo. Vedere Header Annotations per l'elenco completo delle annotazioni utilizzate. Ad esempio"

DWORD 
WINAPI 
GetModuleFileName(
    __in_opt HMODULE hModule, 
    __out_ecount_part(nSize, return + 1) LPTSTR lpFilename, 
    __in DWORD nSize 
    ); 

per questa funzione, hModule è un parametro di input facoltativo, lpFilename è un parametro di output che memorizzare un massimo di nSize elementi di carattere e che conterrà (il valore di ritorno della funzione) +1 elementi carattere nSize è un parametro di input

+1

+1. Questo post di blog ha uno sfondo e altri esempi: http://blogs.msdn.com/michael_howard/archive/2006/05/19/602077.aspx –

+6

Ma quelli non sono macro vuote: alla fine, si espandono in attributi SAL come '[SA_Pre (...)]' e '[SA_Post (...)]', che sono effettivamente gestiti dal compilatore. –

5

A scopo di documentazione, un blocco di commenti ben scritto è sufficiente, quindi questi non hanno alcuno scopo.Inoltre, alcuni parser di commento di documentazione hanno una sintassi speciale per tale una cosa, ad esempio, dato Doxygen, è possibile scrivere:

/** 
* @param[in] param1 ... 
* @param[out] param2 ... 
**/ 
void some_function(int param1, char **param2); 
+0

... ma per quanto riguarda le cose al di fuori della preoccupazione della documentazione? – jldupont

+1

Cosa intendi? Puoi e dovresti documentare tutti i metodi, non solo quelli in API pubbliche. Ai fini della generazione della documentazione, di solito c'è un modo per indicare quali metodi sono "per uso privato", in modo che non entrino nei documenti pubblici, ad es. '\ interno' in Doxygen. –

+0

Se non stai guardando i documenti, stai guardando il codice sorgente. Se non è per lo meno abbastanza ovvio, è necessario refactoring e/o rinominare gli elementi nella fonte invece di decorare. –

4

penso che questa è una cattiva idea. Soprattutto dal momento che chiunque può venire e definire le macro IN/OUT e lasciarti nel mucchio di grossi problemi.

Se davvero si vuole documentarlo mettere commenti in là.

void some_function(/* IN */ int param1, /* OUT */ char **param2); 

Anche perché utilizzare un fuori quando un valore di ritorno funzionerà bene.
Inoltre, preferirei usare pass per ref e const ref per indicare le mie intenzioni. Inoltre, il compilatore ora esegue un ottimo ottimizzazione dell'intento quando il codice è corretto.

void some_function(/* IN */ int const& param1, /* OUT */ char*& param2); 
// OK for int const& is kind of silly but other types may be usefull. 
+0

buon punto ... grazie! – jldupont

+0

@Martin: per quanto riguarda il commento "char *" che hai fatto, ho avuto il mio disclaimer in cima alla domanda ;-) – jldupont

+1

/* +1 */(in contrasto con PLUSONE) –

1

L'unica cosa peggiore, allora questo è stato visto molto tempo fa in un programma C scritto da Pascal dev:


#define begin { 
#define end } 

int main(int argc, char* argv[]) 
begin 
    ... 
end 
0

ho visto l'utilizzo di prefissi i_, o_, io_ oltre alle informazioni in tipi di parametri :

void some_function(int i_param1, char** o_param2, int& io_param3); 
Problemi correlati