Earlier quoted context omitted.
These days it can be chained with _Atomic to achieve the desired effect. That said, oftentimes you need more serious synchronization mechanisms your library would provide.
_Atomic is indeed the correct qualifier to use for unsynchronized cross-thread access. The volatile qualifier doesn't add anything useful on top of that. Really, the only things volatile should be used for are MMIO, debugging, performance testing, and certain situations with signal handlers or setjmp within a single thread.
Lesser known tricks, quirks and features of C
181–189 of 189 posts
Re: Lesser known tricks, quirks and features of C
#182Earlier quoted context omitted.
_Atomic is indeed the correct qualifier to use for unsynchronized cross-thread access. The volatile qualifier doesn't add anything useful on top of that. Really, the only things volatile should be used for are MMIO, debugging, performance testing, and certain situations with signal handlers or setjmp within a single thread.
From what I gather, _Atomic alone will not ensure that the variable contents are actually loaded every time you load them, and can optimize loops away as a result. You'll often want both.
What use case do you have in mind where this theoretical possibility would cause issues?
Re: Lesser known tricks, quirks and features of C
#183Earlier quoted context omitted.
Why are these not compiler errors by default? Opting in to such important safety features seems like broken design.
How could that really work? printf is a library function, not an intrinsic. A function named printf can do anything your heart desires.
> The ISO C90 functions abort, abs, acos, asin, atan2, atan, calloc, ceil, cosh, cos, exit, exp, fabs, floor, fmod, fprintf, fputs, free, frexp, fscanf, isalnum, isalpha, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit, tolower, toupper, labs, ldexp, log10, log, malloc, memchr, memcmp, memcpy, memset, modf, pow, printf, putchar, puts, realloc, scanf, sinh, sin, snprintf, sprintf, sqrt, sscanf, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncat, strncmp, strncpy, strpbrk, strrchr, strspn, strstr, tanh, tan, vfprintf, vprintf and vsprintf are all recognized as built-in functions unless -fno-builtin is specified (or -fno-builtin-function is specified for an individual function).
Builtin here doesn't mean that GCC won't ever emit calls to library functions, only that it reserves not to and allows itselfs to make assumptions about how the functions work, including diagnosing misuse.
The library functions themselves might also be marked with __attribute__(format(...)) as the sibling comment notes but that is not necessarily required for GCC to check the format strings.
Re: Lesser known tricks, quirks and features of C
#184Very nice collection. My favorite C feature is actually a gcc/clang feature : the __INCLUDE_LEVEL__ predefined macro. It made me code&maintain my C projects exactly twice as fast as before because file count dropped to half : https://github.com/milgra/headerlessc .
Re: Lesser known tricks, quirks and features of C
#185Earlier quoted context omitted.
MSVC supports C11 and C17, minus the C99 stuff that was made optional in C11. Anyway given the option, one should always favour C++ over C, if they care about secure code, which while not perfect it is much better than any C compiler will do.
> Anyway given the option, one should always favour C++ over C Eh. I work in embedded, where C reigns supreme. C++ has its own issues in the area, namely that you need to construct your own sub-dialect that removes some features of C++ to make it fit embedded constraints. Commonly, it's C++-but-no-exceptions, sometimes C++-but-no-templates, and others. That said, I'll grant that us embedded developers are effectively…
I can understand exceptions, but what constraints require you to ban templates? If its just code size then it seems a bit arbitrary to ban them completely.
AFAIK most users of C++ do ban some features in their projects so I don't see why that specifically is holding embedded back. Disabling exceptions specifically is something that is not unheard of outside embedded either.
Re: Lesser known tricks, quirks and features of C
#186Fun fact about %n: Mazda cars used to have a bug where they used printf(str) instead of printf("%s", str) and their media system would crash if you tried to play the "99% Invisible" podcast in them. All because the "% In" was parsed as a "%n" with some extra modifiers. https://99percentinvisible.org/episode/the-roman-mars-mazda-...
Re: Lesser known tricks, quirks and features of C
#187 int n = 3, m = 4;
int (*matrix_NxM)[n][m] = malloc(sizeof *matrix_NxM); // `n` and `m` are variables with dimensions known at runtime, not compile time
if (matrix_NxM) {
// (*matrix_NxM)[i][j] = ...;
free(matrix_NxM);
}
Well, that makes much easier a few things I'm doing atm, really glad I read it.Re: Lesser known tricks, quirks and features of C
#188Earlier quoted context omitted.
I found a lot of bugs went away when I switched to STL (Standard Template Library) arrays and ditched managing my own memory. That's C++, I guess it's not available in straight C?
>That's C++, I guess it's not available in straight C? No, because C doesn't have templates. The best you can do for a "vector" in C is macros like above, that also realloc, or write an API around structs for each type.
Re: Lesser known tricks, quirks and features of C
#189Earlier quoted context omitted.
"format not a string literal" is one warning I always upgrade to an error. Dear reader: you should do this, too!
Why are these not compiler errors by default? Opting in to such important safety features seems like broken design.
One practical reason I can think of is because not everyone compiles their own code.
You must most definitely look for and enable such flags as they become available in your own projects. (eg I was rooting for -Wlifetime but it did not land for various reasons)
But when you compile other people's code, your breaking your local build doesn't help anyone. Best you can do is to submit a bug report, which may or may not be ignored.