Dokumen ini menjelaskan gaya kode C yang digunakan oleh Tilen Majerle dalam proyek dan perpustakaannya.
Mari kita mulai dengan kutipan dari situs pengembang Gnome.
Satu -satunya aturan terpenting saat menulis kode adalah ini: periksa kode di sekitarnya dan cobalah meniru .
Sebagai pemelihara, itu mengecewakan untuk menerima tambalan yang jelas dalam gaya pengkodean yang berbeda dengan kode di sekitarnya. Ini tidak sopan, seperti seseorang yang tromping ke rumah bersih dengan sepatu berlumpur.
Jadi, apa pun yang direkomendasikan dokumen ini, jika sudah ada kode tertulis dan Anda menambalnya, jaga agar gaya saat ini konsisten meskipun itu bukan gaya favorit Anda.
VScode hadir dengan alat clang-format
yang sudah dipasang sebelumnya (bagian dari paket LLVM) yang telah dirancang untuk membantu pengembang dengan alat format otomatis selama pengembangan kode.
Dengan demikian, memungkinkan pengguna untuk memformat kode pada perubahan file (dan menyimpan). Saat file disimpan, vScode akan mencoba memohon format dentang dan memformat kode. Aturan yang akan digunakan ada dalam file .clang-format
. Jika dentang-format tidak dapat menemukan aturan di jalur file saat ini, itu akan berjalan sampai ke root, sampai seseorang ditemukan. Jika masih belum ada, aturan default kemudian digunakan.
Repositori ini selalu berisi file .clang-format
yang selalu sesuai dengan aturan yang dijelaskan. Anda dapat menempatkan folder di root atau proyek Anda atau bahkan di root proyek pengembangan perangkat lunak Anda -> Gunakan satu file untuk semua!
Beberapa konfigurasi harus diaktifkan:
Kata kunci tidak boleh , tidak boleh , tidak boleh , tidak boleh , seharusnya , tidak boleh , direkomendasikan , tidak disarankan , mungkin , dan opsional dalam dokumen ini harus ditafsirkan seperti yang dijelaskan dalam BCP 14 [RFC2119] [RFC8174]
Berikut ini terdaftar sebagai aturan umum yang paling jelas dan penting. Silakan periksa dengan cermat sebelum Anda melanjutkan dengan bab -bab lain.
clang-format
harus digunakan dengan file pemformatan yang dilampirkan pada repositori ini (versi 15.x
adalah minimum)C11
4
spasi per level indent1
ruang antara kata kunci dan braket pembukaan /* OK */
if ( condition )
while ( condition )
for ( init ; condition ; step )
do {} while ( condition )
/* Wrong */
if ( condition )
while ( condition )
for ( init ; condition ; step )
do {} while ( condition )
int32_t a = sum ( 4 , 3 ); /* OK */
int32_t a = sum ( 4 , 3 ); /* Wrong */
__
atau _
awalan untuk variabel/fungsi/makro/tipe. Ini dicadangkan untuk bahasa C itu sendiriprv_
NAMA PREFIX UNTUK Fungsi MODUL-MODUL-PRIVATE (STATIC)libname_int_
atau libnamei_
prefix untuk fungsi internal perpustakaan, yang tidak boleh digunakan oleh aplikasi pengguna saat mereka harus digunakan di berbagai modul internal perpustakaan yang berbeda_
Charfor
, while
, do
, switch
, if
, ...) size_t i ;
for ( i = 0 ; i < 5 ; ++ i ) { /* OK */
}
for ( i = 0 ; i < 5 ; ++ i ){ /* Wrong */
}
for ( i = 0 ; i < 5 ; ++ i ) /* Wrong */
{
}
int32_t a ;
a = 3 + 4 ; /* OK */
for ( a = 0 ; a < 5 ; ++ a ) /* OK */
a = 3 + 4 ; /* Wrong */
a = 3 + 4 ; /* Wrong */
for ( a = 0 ; a < 5 ; ++ a ) /* Wrong */
func_name ( 5 , 4 ); /* OK */
func_name ( 4 , 3 ); /* Wrong */
global
ke nilai default apa pun (atau NULL
), terapkan dalam fungsi init
khusus (jika diperlukan). static int32_t a ; /* Wrong */
static int32_t b = 4 ; /* Wrong */
static int32_t a = 0 ; /* Wrong */
Dalam sistem tertanam, sangat umum bahwa ingatan RAM tersebar di berbagai lokasi memori dalam sistem. Dengan cepat menjadi sulit untuk menangani semua kasus, terutama ketika pengguna menyatakan bagian RAM khusus. Script startup bertanggung jawab untuk menetapkan nilai default (.data dan .bss) sementara bagian khusus lainnya mungkin tidak diisi dengan nilai default, yang mengarah ke variabel dengan nilai init tidak akan memiliki efek apa pun.
Agar independen dari masalah tersebut, buat fungsi init untuk setiap modul dan gunakan untuk mengatur nilai default untuk semua variabel Anda, seperti demikian:
static int32_t a ; /* OK */
static int32_t b = 4 ; /* Wrong - this value may not be set at zero
if linker script&startup files are not properly handled */
void
my_module_init ( void ) {
a = 0 ;
b = 4 ;
}
void
my_func ( void ) {
/* 1 */
char a ; /* OK */
/* 2 */
char a , b ; /* OK */
/* 3 */
char a ;
char b ; /* Wrong, variable with char type already exists */
}
int
my_func ( void ) {
/* 1 */
my_struct_t my ; /* First custom structures */
my_struct_ptr_t * p ; /* Pointers too */
/* 2 */
uint32_t a ;
int32_t b ;
uint16_t c ;
int16_t g ;
char h ;
/* ... */
/* 3 */
double d ;
float f ;
}
typedef struct {
int a , b ;
} str_t ;
str_t s = {
. a = 1 ,
. b = 2 , /* Comma here */
}
/* Examples of "complex" structure, with or with missing several trailing commas, after clang-format runs the formatting */
static const my_struct_t my_var_1 = {
. type = TYPE1 ,
. type_data =
{
. type1 =
{
. par1 = 0 ,
. par2 = 1 , /* Trailing comma here */
}, /* Trailing comma here */
}, /* Trailing comma here */
};
static const my_struct_t my_var_2 = {. type = TYPE2 ,
. type_data = {
. type2 =
{
. par1 = 0 ,
. par2 = 1 ,
},
}}; /* Missing comma here */
static const my_struct_t my_var_3 = {. type = TYPE3 ,
. type_data = {. type3 = {
. par1 = 0 ,
. par2 = 1 ,
}}}; /* Missing 2 commas here */
/* No trailing commas - good only for small and simple structures */
static const my_struct_t my_var_4 = {. type = TYPE4 , . type_data = {. type4 = {. par1 = 0 , . par2 = 1 }}};
for
loop /* OK */
for ( size_t i = 0 ; i < 10 ; ++ i )
/* OK, if you need counter variable later */
size_t i ;
for ( i = 0 ; i < 10 ; ++ i ) {
if (...) {
break ;
}
}
if ( i == 10 ) {
}
/* Wrong */
size_t i ;
for ( i = 0 ; i < 10 ; ++ i ) ...
void
a ( void ) {
/* Avoid function calls when declaring variable */
int32_t a , b = sum ( 1 , 2 );
/* Use this */
int32_t a , b ;
b = sum ( 1 , 2 );
/* This is ok */
uint8_t a = 3 , b = 4 ;
}
char
, float
atau double
, selalu gunakan tipe yang dinyatakan di perpustakaan stdint.h
, mis. uint8_t
untuk unsigned 8-bit
, dll.stdbool.h
. Gunakan 1
atau 0
masing -masing untuk true
atau false
/* OK */
uint8_t status ;
status = 0 ;
/* Wrong */
#include <stdbool.h>
bool status = true;
true
, mis. if (check_func() == 1)
, gunakan if (check_func()) { ... }
NULL
void * ptr ;
/* ... */
/* OK, compare against NULL */
if ( ptr == NULL || ptr != NULL ) {
}
/* Wrong */
if ( ptr || ! ptr ) {
}
int32_t a = 0 ;
...
a ++ ; /* Wrong */
++ a ; /* OK */
for ( size_t j = 0 ; j < 10 ; ++ j ) {} /* OK */
size_t
untuk variabel panjang atau ukuranconst
untuk pointer jika fungsi tidak boleh memodifikasi memori yang ditunjuk oleh pointer
const
untuk parameter atau variabel fungsi, jika tidak boleh dimodifikasi /* When d could be modified, data pointed to by d could not be modified */
void
my_func ( const void * d ) {
}
/* When d and data pointed to by d both could not be modified */
void
my_func ( const void * const d ) {
}
/* Not REQUIRED, it is advised */
void
my_func ( const size_t len ) {
}
/* When d should not be modified inside function, only data pointed to by d could be modified */
void
my_func ( void * const d ) {
}
void *
, jangan gunakan uint8_t *
/*
* To send data, function should not modify memory pointed to by `data` variable
* thus `const` keyword is important
*
* To send generic data (or to write them to file)
* any type may be passed for data,
* thus use `void *`
*/
/* OK example */
void
send_data ( const void * data , size_t len ) { /* OK */
/* Do not cast `void *` or `const void *` */
const uint8_t * d = data ; /* Function handles proper type for internal usage */
}
void
send_data ( const void * data , int len ) { /* Wrong, not not use int */
}
sizeof
malloc
C standar dan fungsi free
atau jika perpustakaan/proyek menyediakan alokasi memori khusus, gunakan implementasinya /* OK */
#include <stdlib.h>
void
my_func ( size_t size ) {
int32_t * arr ;
arr = malloc ( sizeof ( * arr ) * n ); /* OK, Allocate memory */
arr = malloc ( sizeof * arr * n ); /* Wrong, brackets for sizeof operator are missing */
if ( arr == NULL ) {
/* FAIL, no memory */
}
free ( arr ); /* Free memory after usage */
}
/* Wrong */
void
my_func ( size_t size ) {
int32_t arr [ size ]; /* Wrong, do not use VLA */
}
boolean
boolean-treated
dengan nol atau satu. Gunakan tidak ( !
) Sebaliknya size_t length = 5 ; /* Counter variable */
uint8_t is_ok = 0 ; /* Boolean-treated variable */
if ( length ) /* Wrong, length is not treated as boolean */
if ( length > 0 ) /* OK, length is treated as counter variable containing multi values, not only 0 or 1 */
if ( length == 0 ) /* OK, length is treated as counter variable containing multi values, not only 0 or 1 */
if ( is_ok ) /* OK, variable is treated as boolean */
if (! is_ok ) /* OK, -||- */
if ( is_ok == 1 ) /* Wrong, never compare boolean variable against 1! */
if ( is_ok == 0 ) /* Wrong, use ! for negative check */
/* comment */
untuk komentar, bahkan untuk komentar satu barisC++
dengan kata kunci extern
dalam file headerstatic
force_redraw
. Jangan gunakan forceRedraw
void *
, mis. uint8_t* ptr = (uint8_t *)func_returning_void_ptr();
sebagai void *
dipromosikan dengan aman ke jenis penunjuk lainnyauint8_t* ptr = func_returning_void_ptr();
alih-alih<
untuk >
Standard Library termasuk file, misalnya. #include <stdlib.h>
""
untuk perpustakaan khusus, mis. #include "my_library.h"
uint8_t* t = (uint8_t*)var_width_diff_type
//
tidak diizinkan. Selalu gunakan /* comment */
, bahkan untuk komentar satu baris //This is comment (wrong)
/* This is comment (ok) */
space+asterisk
untuk setiap baris /*
* This is multi-line comments,
* written in 2 lines (ok)
*/
/**
* Wrong, use double-asterisk only for doxygen documentation
*/
/*
* Single line comment without space before asterisk (wrong)
*/
/*
* Single line comment in multi-line configuration (wrong)
*/
/* Single line comment (ok) */
12
indentasi ( 12 * 4
spasi) offset saat berkomentar. Jika pernyataan lebih besar dari 12
indentasi, buat komentar 4-spaces
selaras (contoh di bawah) ke indentasi berikutnya yang tersedia void
my_func ( void ) {
char a , b ;
a = call_func_returning_char_a ( a ); /* This is comment with 12*4 spaces indent from beginning of line */
b = call_func_returning_char_a_but_func_name_is_very_long ( a ); /* This is comment, aligned to 4-spaces indent */
}
_
underscore /* OK */
void my_func ( void );
void myfunc ( void );
/* Wrong */
void MYFunc ( void );
void myFunc ();
/* OK */
const char * my_func ( void );
my_struct_t * my_func ( int32_t a , int32_t b );
/* Wrong */
const char * my_func ( void );
my_struct_t * my_func ( void );
/* OK, function names aligned */
void set ( int32_t a );
my_type_t get ( void );
my_ptr_t * get_ptr ( void );
/* Wrong */
void set ( int32_t a );
const char * get ( void );
/* OK */
int32_t
foo ( void ) {
return 0 ;
}
/* OK */
static const char *
get_string ( void ) {
return "Hello world!rn" ;
}
/* Wrong */
int32_t foo ( void ) {
return 0 ;
}
_
opsional /* OK */
int32_t a ;
int32_t my_var ;
int32_t myvar ;
/* Wrong */
int32_t A ;
int32_t myVar ;
int32_t MYVar ;
type
void
foo ( void ) {
int32_t a , b ; /* OK */
char a ;
char b ; /* Wrong, char type already exists */
}
void
foo ( void ) {
int32_t a ;
a = bar ();
int32_t b ; /* Wrong, there is already executable statement */
}
int32_t a , b ;
a = foo ();
if ( a ) {
int32_t c , d ; /* OK, c and d are in if-statement scope */
c = foo ();
int32_t e ; /* Wrong, there was already executable statement inside block */
}
/* OK */
char * a ;
/* Wrong */
char * a ;
char * a ;
/* OK */
char * p , * n ;
_
yang opsional di antara kata -katatypedef
Ketika struktur dinyatakan, dapat menggunakan salah satu dari 3
opsi berbeda:
_t
setelah namanya. struct struct_name {
char * a ;
char b ;
};
_t
setelah namanya. typedef struct {
char * a ;
char b ;
} struct_name_t ;
_t
untuk nama dasar dan harus berisi akhiran _t
setelah namanya untuk bagian typedef. typedef struct struct_name { /* No _t */
char * a ;
char b ;
char c ;
} struct_name_t ; /* _t */
Contoh deklarasi buruk dan koreksi yang disarankan mereka
/* a and b MUST be separated to 2 lines */
/* Name of structure with typedef MUST include _t suffix */
typedef struct {
int32_t a , b ;
} a ;
/* Corrected version */
typedef struct {
int32_t a ;
int32_t b ;
} a_t ;
/* Wrong name, it MUST not include _t suffix */
struct name_t {
int32_t a ;
int32_t b ;
};
/* Wrong parameters, MUST be all uppercase */
typedef enum {
MY_ENUM_TESTA ,
my_enum_testb ,
} my_enum_t ;
C99
/* OK */
a_t a = {
. a = 4 ,
. b = 5 ,
};
/* Wrong */
a_t a = { 1 , 2 };
_fn
sufiks /* Function accepts 2 parameters and returns uint8_t */
/* Name of typedef has `_fn` suffix */
typedef uint8_t ( * my_func_typedef_fn )( uint8_t p1 , const char * p2 );
1
pernyataan bersarang1
ukuran indentasi untuk setiap sarang /* OK */
if ( c ) {
do_a ();
} else {
do_b ();
}
/* Wrong */
if ( c )
do_a ();
else
do_b ();
/* Wrong */
if ( c ) do_a ();
else do_b ();
if
atau if-else-if
, else
harus berada di baris yang sama dengan braket penutupan pernyataan pertama /* OK */
if ( a ) {
} else if ( b ) {
} else {
}
/* Wrong */
if ( a ) {
}
else {
}
/* Wrong */
if ( a ) {
}
else
{
}
do-while
, while
bagian harus berada di baris yang sama dengan braket penutupan do
/* OK */
do {
int32_t a ;
a = do_a ();
do_b ( a );
} while ( check ());
/* Wrong */
do
{
/* ... */
} while ( check ());
/* Wrong */
do {
/* ... */
}
while ( check ());
if ( a ) {
do_a ();
} else {
do_b ();
if ( c ) {
do_c ();
}
}
if ( a ) do_b ();
else do_c ();
if ( a ) do_a (); else do_b ();
while
, do-while
atau for
loop harus menyertakan kurung /* OK */
while ( is_register_bit_set ()) {}
/* Wrong */
while ( is_register_bit_set ());
while ( is_register_bit_set ()) { }
while ( is_register_bit_set ()) {
}
while
(atau for
, do-while
, dll) kosong (bisa menjadi kasus dalam pemrograman tertanam), gunakan tanda kurung satu baris kosong /* Wait for bit to be set in embedded hardware unit */
volatile uint32_t * addr = HW_PERIPH_REGISTER_ADDR ;
/* Wait bit 13 to be ready */
while ( * addr & ( 1 << 13 )) {} /* OK, empty loop contains no spaces inside curly brackets */
while ( * addr & ( 1 << 13 )) { } /* Wrong */
while ( * addr & ( 1 << 13 )) { /* Wrong */
}
while ( * addr & ( 1 << 13 )); /* Wrong, curly brackets are missing. Can lead to compiler warnings or unintentional bugs */
for
, do-while
, while
/* Not recommended */
int32_t a = 0 ;
while ( a < 10 ) {
.
..
...
++ a ;
}
/* Better */
for ( size_t a = 0 ; a < 10 ; ++ a ) {
}
/* Better, if inc may not happen in every cycle */
for ( size_t a = 0 ; a < 10 ; ) {
if (...) {
++ a ;
}
}
if
pernyataan hanya dapat digunakan untuk operasi penugasan atau fungsi panggilan /* OK */
int a = condition ? if_yes : if_no ; /* Assignment */
func_call ( condition ? if_yes : if_no ); /* Function call */
switch ( condition ? if_yes : if_no ) {...} /* OK */
/* Wrong, this code is not well maintenable */
condition ? call_to_function_a () : call_to_function_b ();
/* Rework to have better program flow */
if ( condition ) {
call_to_function_a ();
} else {
call_to_function_b ();
}
case
break
dalam setiap case
atau pernyataan default
/* OK, every case has single indent */
/* OK, every break has additional indent */
switch ( check ()) {
case 0 :
do_a ();
break ;
case 1 :
do_b ();
break ;
default :
break ;
}
/* Wrong, case indent missing */
switch ( check ()) {
case 0 :
do_a ();
break ;
case 1 :
do_b ();
break ;
default :
break ;
}
/* Wrong */
switch ( check ()) {
case 0 :
do_a ();
break ; /* Wrong, break MUST have indent as it is under case */
case 1 :
do_b (); /* Wrong, indent under case is missing */
break ;
default :
break ;
}
default
/* OK */
switch ( var ) {
case 0 :
do_job ();
break ;
default :
break ;
}
/* Wrong, default is missing */
switch ( var ) {
case 0 :
do_job ();
break ;
}
break
di dalam.case
switch ( a ) {
/* OK */
case 0 : {
int32_t a , b ;
char c ;
a = 5 ;
/* ... */
break ;
}
/* Wrong */
case 1 :
{
int32_t a ;
break ;
}
/* Wrong, break shall be inside */
case 2 : {
int32_t a ;
}
break ;
}
_
opsional, kecuali jika mereka ditandai dengan jelas sebagai fungsi yang mungkin di masa depan diganti dengan sintaks fungsi reguler /* OK */
#define SQUARE ( x ) ((x) * (x))
/* Wrong */
#define square ( x ) ((x) * (x))
/* OK */
#define MIN ( x , y ) ((x) < (y) ? (x) : (y))
/* Wrong */
#define MIN ( x , y ) x < y ? x : y
/* Wrong */
#define MIN ( x , y ) (x) < (y) ? (x) : (y)
#define SUM ( x , y ) (x) + (y)
/* Imagine result of this equation using wrong SUM implementation */
int32_t x = 5 * SUM ( 3 , 4 ); /* Expected result is 5 * 7 = 35 */
int32_t x = 5 * ( 3 ) + ( 4 ); /* It is evaluated to this, final result = 19 which is not what we expect */
/* Correct implementation */
#define MIN ( x , y ) ((x) < (y) ? (x) : (y))
#define SUM ( x , y ) ((x) + (y))
do {} while (0)
typedef struct {
int32_t px , py ;
} point_t ;
point_t p ; /* Define new point */
/* Wrong implementation */
/* Define macro to set point */
#define SET_POINT ( p , x , y ) (p)->px = (x); (p)->py = (y) /* 2 statements. Last one should not implement semicolon */
SET_POINT ( & p , 3 , 4 ); /* Set point to position 3, 4. This evaluates to... */
( & p ) -> px = ( 3 ); ( & p ) -> py = ( 4 ); /* ... to this. In this example this is not a problem. */
/* Consider this ugly code, however it is valid by C standard (not recommended) */
if ( a ) /* If a is true */
if ( b ) /* If b is true */
SET_POINT ( & p , 3 , 4 ); /* Set point to x = 3, y = 4 */
else
SET_POINT ( & p , 5 , 6 ); /* Set point to x = 5, y = 6 */
/* Evaluates to code below. Do you see the problem? */
if ( a )
if ( b )
( & p ) -> px = ( 3 ); ( & p ) -> py = ( 4 );
else
( & p ) -> px = ( 5 ); ( & p ) -> py = ( 6 );
/* Or if we rewrite it a little */
if ( a )
if ( b )
( & p ) -> px = ( 3 );
( & p ) -> py = ( 4 );
else
( & p ) -> px = ( 5 );
( & p ) -> py = ( 6 );
/*
* Ask yourself a question: To which `if` statement does the `else` keyword belong?
*
* Based on first part of code, answer is straight-forward. To inner `if` statement when we check `b` condition
* Actual answer: Compilation error as `else` belongs nowhere
*/
/* Better and correct implementation of macro */
#define SET_POINT ( p , x , y ) do { (p)->px = (x); (p)->py = (y); } while (0) /* 2 statements. No semicolon after while loop */
/* Or even better */
#define SET_POINT ( p , x , y ) do { /* Backslash indicates statement continues in new line */
( p ) -> px = ( x );
( p ) -> py = ( y );
} while ( 0 ) /* 2 statements. No semicolon after while loop */
/* Now original code evaluates to */
if ( a )
if ( b )
do { ( & p ) -> px = ( 3 ); ( & p ) -> py = ( 4 ); } while ( 0 );
else
do { ( & p ) -> px = ( 5 ); ( & p ) -> py = ( 6 ); } while ( 0 );
/* Every part of `if` or `else` contains only `1` inner statement (do-while), hence this is valid evaluation */
/* To make code perfect, use brackets for every if-ifelse-else statements */
if ( a ) { /* If a is true */
if ( b ) { /* If b is true */
SET_POINT ( & p , 3 , 4 ); /* Set point to x = 3, y = 4 */
} else {
SET_POINT ( & p , 5 , 6 ); /* Set point to x = 5, y = 6 */
}
}
#ifdef
atau #ifndef
. Gunakan defined()
atau !defined()
sebagai gantinya #ifdef XYZ
/* do something */
#endif /* XYZ */
if/elif/else/endif
pernyataan /* OK */
#if defined( XYZ )
/* Do if XYZ defined */
#else /* defined(XYZ) */
/* Do if XYZ not defined */
#endif /* !defined(XYZ) */
/* Wrong */
#if defined( XYZ )
/* Do if XYZ defined */
#else
/* Do if XYZ not defined */
#endif
#if
/* OK */
#if defined( XYZ )
#if defined( ABC )
/* do when ABC defined */
#endif /* defined(ABC) */
#else /* defined(XYZ) */
/* Do when XYZ not defined */
#endif /* !defined(XYZ) */
/* Wrong */
#if defined( XYZ )
#if defined( ABC )
/* do when ABC defined */
#endif /* defined(ABC) */
#else /* defined(XYZ) */
/* Do when XYZ not defined */
#endif /* !defined(XYZ) */
Kode yang didokumentasikan memungkinkan Doxygen untuk menguraikan dan menghasilkan output HTML/PDF/LATEX, sehingga sangat penting untuk melakukannya dengan benar pada tahap awal proyek.
variables
, functions
dan structures/enumerations
untuk doxygen, jangan gunakan @
5x4
Spaces ( 5
tab) Offset dari awal baris untuk teks /**
* brief Holds pointer to first entry in linked list
* Beginning of this text is 5 tabs (20 spaces) from beginning of line
*/
static
type_t * list ;
/**
* brief This is point struct
* note This structure is used to calculate all point
* related stuff
*/
typedef struct {
int32_t x ; /*!< Point X coordinate */
int32_t y ; /*!< Point Y coordinate */
int32_t size ; /*!< Point size.
Since comment is very big,
you may go to next line */
} point_t ;
/**
* brief Point color enumeration
*/
typedef enum {
COLOR_RED , /*!< Red color */
COLOR_GREEN , /*!< Green color */
COLOR_BLUE , /*!< Blue color */
} point_color_t ;
brief
dan semua parameterin
atau out
untuk input dan output masing -masingreturn
jika mengembalikan sesuatu. Ini tidak berlaku untuk fungsi void
note
atau warning
:
antara nama parameter dan deskripsinya /**
* brief Sum `2` numbers
* param[in] a: First number
* param[in] b: Second number
* return Sum of input values
*/
int32_t
sum ( int32_t a , int32_t b ) {
return a + b ;
}
/**
* brief Sum `2` numbers and write it to pointer
* note This function does not return value, it stores it to pointer instead
* param[in] a: First number
* param[in] b: Second number
* param[out] result: Output variable used to save result
*/
void
void_sum ( int32_t a , int32_t b , int32_t * result ) {
* result = a + b ;
}
ref
untuk menentukan yang mana /**
* brief My enumeration
*/
typedef enum {
MY_ERR , /*!< Error value */
MY_OK /*!< OK value */
} my_enum_t ;
/**
* brief Check some value
* return ref MY_OK on success, member of ref my_enum_t otherwise
*/
my_enum_t
check_value ( void ) {
return MY_OK ;
}
NULL
) untuk konstanta atau angka /**
* brief Get data from input array
* param[in] in: Input data
* return Pointer to output data on success, `NULL` otherwise
*/
const void *
get_data ( const void * in ) {
return in ;
}
hideinitializer
Doxygen /**
* brief Get minimal value between `x` and `y`
* param[in] x: First value
* param[in] y: Second value
* return Minimal value between `x` and `y`
* hideinitializer
*/
#define MIN ( x , y ) ((x) < (y) ? (x) : (y))
file
dan deskripsi brief
diikuti oleh garis kosong (saat menggunakan doxygen) /**
* file template.h
* brief Template include file
*/
/* Here is empty line */
/**
* file template.h
* brief Template include file
*/
/*
* Copyright (c) year FirstName LASTNAME
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* This file is part of library_name.
*
* Author: FirstName LASTNAME <[email protected]>
*/
#ifndef
C++
C++
periksaextern
for Global Module Variabel dalam file header, tentukan mereka dalam file sumber nanti /* file.h ... */
#ifndef ...
extern int32_t my_variable; /* This is global variable declaration in header */
#endif
/* file.c ... */
int32_t my_variable; /* Actually defined in source */
Tidak pernah menyertakan file .c
di file .c
lainnya
File .c
harus terlebih dahulu menyertakan file .h
yang sesuai, kemudian yang lain, kecuali jika perlu secara eksplisit diperlukan
Jangan sertakan deklarasi pribadi modul dalam file header
Contoh file header (tidak ada lisensi demi contoh)
/* License comes here */
#ifndef TEMPLATE_HDR_H
#define TEMPLATE_HDR_H
/* Include headers */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* File content here */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* TEMPLATE_HDR_H */
Repositori hadir dengan file .clang-format
yang selalu ada di atas, konfigurasi input untuk alat clang-format
. Ini dapat diintegrasikan dengan mulus dengan sebagian besar IDE Techno terbaru, termasuk VScode. Memformat kemudian terjadi di tempat di setiap file simpan.
https://code.visualstudio.com/docs/cpp/cpp-ide#_code-formatting
Astyle adalah perangkat lunak yang hebat yang dapat membantu memformat kode berdasarkan konfigurasi input.
Repositori ini berisi file astyle-code-format.cfg
yang dapat digunakan dengan perangkat lunak AStyle
.
astyle --options="astyle-code-format.cfg" "input_path/*.c,*.h" "input_path2/*.c,*.h"
Konfigurasi gaya artistik sudah usang dan tidak lagi diperbarui
Repositori berisi file eclipse-ext-kr-format.xml
yang dapat digunakan dengan toolchain berbasis Eclipse untuk mengatur opsi formatter.
Ini didasarkan pada formatter K&R dengan modifikasi untuk menghormati aturan di atas. Anda dapat mengimpornya dalam pengaturan Eclipse, Preferences -> LANGUAGE -> Code Style -> Formatter
.