1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #ifndef __CONSTANTS_H__
#define __CONSTANTS_H__
void print_constants();
//enum { constant_int = 65 };
//──────────────────────────────────────────────────
// GOOD
#ifndef BAD // gcc …
static const int constant_int = 65;
static const char* constant_string = "sixty-five";
static const float constant_float = 65.05;
//──────────────────────────────────────────────────
// BAD strategy #1: Use #define
//
// Problem: Type might not be what you expect.
#elif BAD==2 // gcc -DBAD=2
#define constant_int 65
#define constant_string "sixty-five"
#define constant_float 65.05
//│ $ gcc -DBAD=2 constants_1.c constants_2.c
//│ /tmp/ccEXHgr8.o:(.rodata+0x0): multiple definition of `constant_int'
//│ /tmp/cclf5nhb.o:(.rodata+0x0): first defined here
//│ /tmp/ccOHc2wE.o:(.data+0x0): multiple definition of `constant_string'
//│ /tmp/ccpaprle.o:(.data+0x0): first defined here
//│ /tmp/ccOHc2wE.o:(.rodata+0xc): multiple definition of `constant_float'
//│ /tmp/ccpaprle.o:(.rodata+0xc): first defined here
//│ collect2: error: ld returned 1 exit status
//──────────────────────────────────────────────────
// BAD strategy #1: const «type»
//
// Problem: If you #include it from multiple files, you get linker errors.
#elif BAD==2 // gcc -DBAD=1 …
const int constant_int = 65;
const char* constant_string = "sixty-five";
const float constant_float = 65.05;
//│ $ gcc -DBAD=1 constants_1.c constants_2.c
//│ /tmp/ccEXHgr8.o:(.rodata+0x0): multiple definition of `constant_int'
//│ /tmp/cclf5nhb.o:(.rodata+0x0): first defined here
//│ /tmp/ccOHc2wE.o:(.data+0x0): multiple definition of `constant_string'
//│ /tmp/ccpaprle.o:(.data+0x0): first defined here
//│ /tmp/ccOHc2wE.o:(.rodata+0xc): multiple definition of `constant_float'
//│ /tmp/ccpaprle.o:(.rodata+0xc): first defined here
//│ collect2: error: ld returned 1 exit status
//──────────────────────────────────────────────────
// BAD strategy #3: static const «type»
//
// Problem: If you don't use every constant in every file where it is #include'd,
// then you get an error.
#elif BAD==3 // gcc -DBAD=3 …
static const int constant_int = 65;
static const char* constant_string = "sixty-five";
static const float constant_float = 65.05;
static const char* constant_unused = "UNUSED";
//│ $ gcc -DBAD=1 constants_1.c constants_2.c
//│ /tmp/ccEXHgr8.o:(.rodata+0x0): multiple definition of `constant_int'
//│ /tmp/cclf5nhb.o:(.rodata+0x0): first defined here
//│ /tmp/ccOHc2wE.o:(.data+0x0): multiple definition of `constant_string'
//│ /tmp/ccpaprle.o:(.data+0x0): first defined here
//│ /tmp/ccOHc2wE.o:(.rodata+0xc): multiple definition of `constant_float'
//│ /tmp/ccpaprle.o:(.rodata+0xc): first defined here
//│ collect2: error: ld returned 1 exit status
#endif
#endif /* end of include guard: __CONSTANTS_H__ */
|
© Copyright 2020 Alexander J. Quinn This content is protected and may not be shared, uploaded, or distributed.