There's nothing "C99" about that ARRAY_SIZE macro, of course.
That said, I'm rather sceptical towards it, I think it's better written as-is.
Otherwise, the question "does SIZE mean bytes, or number of elements?" always arises to haunt me. Once you need to keep looking stuff like that up, the macro isn't helping.
In actual code, the name of the array never needs to be enclosed in parentheses so it's often clearer too. E.g. something like:
int fourk[4096];
for(size_t i = 0; i < sizeof fourk / sizeof *fourk; ++i)
...
I realize that it's not 100% DRY to repeat the array name, but I think it's a small price to pay for not having to use a non-standard macro that requires learning. It's all about friction.
I use the convention "size = number of bytes" (as in sizeof), "count = number of elements" and so my sizeof(x)/sizeof(x[0]) macro is actually called COUNT.
Thank you. I did not know about this, I've been using the long version. nitems is defined in sys/param.h in OpenBSD and FreeBSD in case anyone is interested.
I use that macro frequently but warily. The fact that it only works with static arrays and (AFAIK) the compiler won't warn you if you accidentally use it on dynamic arrays/pointers/array parameters is a big risk.
Come to think of it, I'm afraid I'm leaving a time bomb for the next inexperienced maintainer who doesn't know the limitations.
These are GNU C tricks! Fine anyway, I think I especially like those that are ISO C. Trick number one is a C11 feature -- anonymous struct members in structs and unions, though I will not vouch for its validity without consulting with my C11 standard handbook.
Oh, and by the way, why not use X macros in the form where the macro to apply is passed as the argument? #define SPRITES(S) S(1, 2, 3) S(2, 3, 4) etc.
As a note to anyone interested in what's in the standards: the C committee openly publishes its work in progress, including documents that are functionally identical to the official standards except for the working at the front that says ‘this is an official standard’.
I usually don't use those flags because some extensions are well supported (as long as I stay away from MSVC), and so I feel free to use them if they help me. One example is the ##__VAR_ARGS__ gnu extension that is not strictly c99, but not using it is just too painful for variadic macros.
Various bits of numerical analysis. The overall framework and plumbing is written in Python, as are all the algorithms initially. Then for those that are too slow, or need to be run lots of times, algorithms are reimplemented in C as a Python extensions.
The existing Python implementation then helps with debugging and testing.
I have. The project is an event based http server and client. Mostly I work with libevent, redis, and openssl. We don't build our software on Windows so we don't have to worry about the limitations on that platform (non-POSIX mostly).
You can use GCC and Clang directly on Windows, both implement 100% C99. Alternatively, Visual Studio 2013 implements most of the C99 standard (not a complete implementation though).
You don't need to install MinGW or MSYS in order to use GCC (I assume you are interested only in C99 here and not in POSIX programming). Here is an example of a standalone GCC (contains C, C++ and Fortran compilers):
Compilation times, no need for inheritance and the fact that most libraries I'm using are written in C were the reasons I chose C over C++ or something else.
Yes, I have and I found this was useful. Would like more sites like this or a central location for standard tricks which are tagged as being C99 or GNU specific.
It's very useful; I've long done the same thing. Though - you do need to do something so you can examine the error value. Even though OpenGL's error enum is terribly vague, most functions can produce more than one type of error. It's nice to be able to see what the value was, even if only to verify your assumption that what's obviously the case is indeed actually happening. Store the value somewhere global so you can examine it in the debugger when the program's stopped, or (if you have such a thing) use some fancier assert macro that prints out the problem values.
Also look up GL_ARB_debug_output - https://www.opengl.org/registry/specs/ARB/debug_output.txt. I don't remember this ever telling me anything terribly useful for debugging, but I did get a couple of perf hints from it... anyway, it's vendor-specific, so on OS X, maybe it will help.
(BTW - if you ever end up using Direct3D on Windows, be sure to activate the debug runtime. Compare and contrast.)
I put a simplified version in the article to make it simple, but the macro I actually use in my games is slightly more advanced, and will output more informations about the error and its context.
Ah, right! - my first version was just the assert, and it was working fine until one day I ended up on a wild goose chase because I was certain it had to be GL_INVALID_OPERATION. But in fact... it was GL_INVALID_ENUM :) So I just thought I'd save somebody a couple of minutes.
A common pattern in embedded C is to use something like "goto fail" instead of assert, wrap your function calls in this sort of macro, and then do error handling in one place at the end of the function.
I use that style too, but I've not found it useful for OpenGL. When you're developing your product, you want every OpenGL error to explode in your face, so you know it happened. In your final build, you probably won't ever check, because... well, what will you do if something happens? OpenGL errors are much more like ENOMEM than they are like ENOENT, and if you get one in production, you're basically stuffed. The best thing you can do is just carry on and hope that the driver ignores it correctly! (One advantage to working on code whose primary purpose is merely to display something on the screen: you can do stuff like that, and it's OK.)
There are exceptions to this general rule, and sometimes you do need to use glGetError in the normal run of things, and take action based on the result. But they are very much exceptions.
Okay, so as someone who is ramping up on C where would I go to learn all these common patterns? I could start going through github repos and start reading code but this seems very inefficient and I might pick up something that is actually a bad technique.
Another useful OpenGL macro, at least for me, is this one:
#define GLSL(str) (char*)"#version 330\n" #str
It basically enables you to embed quick snippets of GLSL inside your C code, instead of using concatenated strings. Example:
char* fragShader = GLSL(
in vec3 uv;
out vec4 color;
uniform sampler2DArray tex;
void main()
{
// Comments work too
color = texture(tex, uv);
}
);
In Sublime Text you even get code completion and color highlighting, since GLSL and C look so alike.
I believe it might work for OpenCL Kernels too.
The only downside is that it doesn't add line breaks by itself (hence the "#version 330\n", which requires a line break), so GLSL Compilation errors aren't as useful.
If you use C++ you might be interested in glbinding (https://github.com/hpicgs/glbinding). It allows you to define an after callback which can be defined as a function that checks for errors. It also has a few other improvements over GLEW.
Isn't there some C11 version of the language that would add those kinds of features ? I guess they might break earlier C code though, but I'm not sure.
These really aren't the features you'd add in a language version though honestly. Maybe the standard library, but even then these are so simple that IMO it's not worth adding them. For a lot of these, a big reason they're not in the language is because they work if you understand what they're doing, but they don't work in every context and you get strange errors in those cases.
Ex. ARRAY_SIZE works by simply using 'sizeof' to find the size of the array. This only works if the array was defined earlier in the same section of code though, it doesn't work on say, arrays passed to functions. So the name 'ARRAY_SIZE' for this macro is misleading because it only works on some arrays in some instances. Anybody who's programmed in C would know this, but they could probably write their own macro to do this anyway. It's beginners who wouldn't know how to write this macro, and would also be confused by how it works.
The thing you might consider standardizing is the GNU extensions that they used in this article, naming ({ }) and typeof. Both can be handy honestly, but C11 doesn't standardize either IIRC.
I'm pretty sure Clang supports C11 well too, didn't find a corresponding table though. It says "By default, Clang builds C code in GNU C11 mode [...]" on this page: http://clang.llvm.org/compatibility.html.
“Clang strives to both conform to current language standards (up to C11 and C++11)”. If anything's missing, it's a bug. clang also kindly defaults to C11 so I don't have to curse and go add a command line flag every time I write “for (int i = ...”.
Sorry, I was misremembering the edge case here, which indeed is still around pointer decay:
#include <stdio.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
void p (int* a) {
printf("ARRAY_SIZE of arr = %lu, %lu, %lu\n", ARRAY_SIZE(a), sizeof(a), sizeof((a)[0]));
}
int main () {
int arr [] = {0, 1, 2, 3, 4};
printf("ARRAY_SIZE of arr = %lu, %lu, %lu\n", ARRAY_SIZE(arr), sizeof(arr), sizeof((arr)[0]));
p(arr);
}
prints:
ARRAY_SIZE of arr = 5, 20, 4
ARRAY_SIZE of arr = 2, 8, 4
where in the function, the arr has decayed into a pointer losing the additional info about size (now the size of a pointer 8bytes or 64bits on my host). Which is why you usually get the length of the array before invoking the function and pass it in as additional information, or wrap the complete array in a struct to preserve sizeof info (http://spin.atomicobject.com/2014/03/25/c-single-member-stru...).
but what he means by A on the RHS, I think, is that you must take into account the fact that A_LHS might be zero. You can't really write this identity and give a constant on the right, so he wrote the next best thing.
That said, I'm rather sceptical towards it, I think it's better written as-is.
Otherwise, the question "does SIZE mean bytes, or number of elements?" always arises to haunt me. Once you need to keep looking stuff like that up, the macro isn't helping.
In actual code, the name of the array never needs to be enclosed in parentheses so it's often clearer too. E.g. something like:
I realize that it's not 100% DRY to repeat the array name, but I think it's a small price to pay for not having to use a non-standard macro that requires learning. It's all about friction.