1# C style guide 2 3<!--* 4# Document freshness: For more information, see go/fresh-source. 5freshness: { owner: 'haberman' reviewed: '2024-02-05' } 6*--> 7 8Since upb is written in pure C, we supplement the 9[Google C++ style guide](https://google.github.io/styleguide/cppguide.html) with 10some C-specific guidance. 11 12Everything written here is intended to follow the spirit of the C++ style guide. 13 14upb is currently inconsistent about following these conventions. It is intended 15that all code will be updated to match these guidelines. The priority is 16converting public interfaces as these are more difficult to change later. 17 18## Naming 19 20### Functions and Types 21 22C does not have namespaces. Anywhere you would normally use a namespace 23separator (`::`) in C++, we use an underscore (`_`) in C: 24 25```c++ 26// C equivalent for upb::Arena::New() 27upb_Arena* upb_Arena_New(); 28``` 29 30Since we rely on `_` to be our namespace separator, we never use it to merely 31separate words in function or type names: 32 33```c++ 34// BAD: this would be interpreted as upb::FieldDef::has::default(). 35bool upb_FieldDef_has_default(const upb_FieldDef* f); 36 37// GOOD: this is equivalent to upb::FieldDef::HasDefault(). 38bool upb_FieldDef_HasDefault(const upb_FieldDef* f); 39``` 40 41For multi-word namespaces, we use `PascalCase`: 42 43```c++ 44// `PyUpb` is the namespace. 45PyObject* PyUpb_CMessage_GetAttr(PyObject* _self, PyObject* attr); 46``` 47 48### Private Functions and Members 49 50Since we do not have `private` in C++, we use the `UPB_PRIVATE()` macro to mark 51internal functions and variables that should only be accessed from upb: 52 53```c++ 54// Internal-only function. 55int64_t UPB_PRIVATE(upb_Int64_FromLL)(); 56 57// Internal-only members. Underscore prefixes are only necessary when the 58// structure is defined in a header file. 59typedef struct { 60 const int32_t* UPB_PRIVATE(values); 61 uint64_t UPB_PRIVATE(mask); 62 int UPB_PRIVATE(value_count); 63} upb_MiniTableEnum; 64 65// Using these members in an internal function. 66int upb_SomeFunction(const upb_MiniTableEnum* e) { 67 return e->UPB_PRIVATE(value_count); 68} 69``` 70 71This prevents users from accessing these symbols, because `UPB_PRIVATE()` 72is defined in `port_def.inc` and undefined in `port_undef.inc`, and these 73textual headers are not accessible by users. 74 75It is only necessary to use `UPB_PRIVATE()` for things defined in headers. 76For symbols in `.c` files, it is sufficient to mark private functions with 77`static`. 78