I was taking a look at the Quake 1 GPL Code and I came across various similar header files, the purpose or use of which I don't seem to understand. They look like tables of some sorts and are structured like this
{1, 0},
{1, -1},
{1, -2},
{1, -3},
{1, -4},
{1, -5},[...]
Without anything before or after them. I understand they define something but I've never come across this kind of notation in C.
You can read one of the header files I'm referring to here.
My question is: what are those...things? The ASM is actually giving me less problems than that stuff.
These are probably multi-use includes. They can be used like so:
struct {int y; int y;} points[] = {
#include <points.inl>
};
The contents of a header do not have to be valid C; the C preprocessor will insert them wherever the #include directive is found, such as in the middle of a struct initialization in another source file. As long as it's valid C by the time it actually gets to the compiler, that's all that matters.
They can be used to initialize arrays.
You could use them like this:
int array[N][2] =
#include <header_file>
;
Related
I have an array declared in my header file like this:
int snapshot[kSnapshotSize];
which I would really love to init like this in my implementation file:
snapshot[kSnapshotSize] = {[0 ... kSnapshotSize-1] = 5};
however the compiler complains: "Expected expression"
Can anyone tell me what I'm doing wrong?
UPDATE: int snapshot[kSnapshotSize] = {[0 ... kSnapshotSize] = 5}; seems to work, so probably I'm missing something basic. I think I can use memset, but would first want to be sure this is not possible (and why)
UPDATE 2: As many of you pointed out, it seems that it's only possible to init an array like that not to populate it later. I end up using a for loop.
I presume you mean
int snapshot[kSnapshotSize] = {[0 ... kSnapshotSize - 1] = 5};
But that use of ... is a gcc-specific extension. If you don't mind being limited to gcc, that's ok.
memset() won't work; it sets each byte of the target to the specified value.
For portability, your best bet is to use an explicit loop to set each element.
I have declared a structure called time, containing 3 integer members called sec, min, and hour. From there, I define a structure variable of type time called today. If I initialize the variable at this point, everything works struct time today = {3, 4, 5}; However, if I split this into two steps and try to assign values to the structure variable today with a compound literal, as in:
struct time today; today = (struct time) {3, 4, 5}; then gcc yells and tells me that the second instance of today was already defined. This is pretty much a clone of an example from "Programming in C" third edition, by Stephen Kochan, 2005. It also seems legit from several other websites that discuss structures. Has something changed since C99 or is there something that I am missing. I am running this in Visual Studio Code 1.53 with MinGW.
Thanks
#include <stdio.h>
struct time
{ int hour;
int min;
int sec;
};
struct time today;
today = (struct time) {7, 5, 9};
int main (void)
{
printf("sec = %i", today.sec);
return 0;
}
Maybe if I stick with this long enough, I might actually start to understand what I'm doing. I put the structure in global space, so I just put all of the structure stuff there as well. Moving the assignment into the Main makes everything work just fine. DUH. Thanks for being patient with me. Tim
I have an array declared in my header file like this:
int snapshot[kSnapshotSize];
which I would really love to init like this in my implementation file:
snapshot[kSnapshotSize] = {[0 ... kSnapshotSize-1] = 5};
however the compiler complains: "Expected expression"
Can anyone tell me what I'm doing wrong?
UPDATE: int snapshot[kSnapshotSize] = {[0 ... kSnapshotSize] = 5}; seems to work, so probably I'm missing something basic. I think I can use memset, but would first want to be sure this is not possible (and why)
UPDATE 2: As many of you pointed out, it seems that it's only possible to init an array like that not to populate it later. I end up using a for loop.
I presume you mean
int snapshot[kSnapshotSize] = {[0 ... kSnapshotSize - 1] = 5};
But that use of ... is a gcc-specific extension. If you don't mind being limited to gcc, that's ok.
memset() won't work; it sets each byte of the target to the specified value.
For portability, your best bet is to use an explicit loop to set each element.
In C, when defining an array I can do the following:
int arr[] = {5, 2, 9, 8};
And thus I defined it and filled it up, but how do I define it in my .h file, and then fill it in my .c?
Like do something like
int arr[];
arr = {5, 2, 9, 8};
I'm pretty new to C, not sure how it would look
any suggestions?
Normally, you'd put:
extern int arr[];
In the .h file, and:
int arr[] = { 5, 2, 9, 8};
In the .c file.
Edit: Dale Hagglund and KevinDTimm raise good points: you only want to put the initialization in one .c file, and you only need to put anything in the .h file if you're going to access arr from code in more than one .c file.
You can use include guards to prevent the assignemnt from happening multiple times, but putting the assignment into headers is a very bad practice in my opinion. Put the intialization in a c file, in an init function instead and extern the array in the h file.
I want to create a constant static array to be used throughout my Objective-C implementation file similar to something like this at the top level of my ".m" file:
static const int NUM_TYPES = 4;
static int types[NUM_TYPES] = {
1,
2,
3,
4 };
I plan on using NUM_TYPES later on in the file so I wanted to put it in a variable.
However, when I do this, I get the error
"Variably modified 'types' at file scope"
I gather that this may have something to do with the array size being a variable (I don't get this message when I put an integer literal there, like static int types[4]).
I want to fix this, but maybe I am going about it all wrong...I have 2 goals here:
To have an array which is accessible throughout the file
To encapsulate NUM_TYPES into a variable so I don't have the same literal scattered about different places in my file
Any suggestions?
[EDIT]
Found this in the C Faq: http://c-faq.com/ansi/constasconst.html
The reason for this warning is that const in c doesn't mean constant. It means "read only". So the value is stored at a memory address and could potentially be changed by machine code.
If you're going to use the preprocessor anyway, as per the other answers, then you can make the compiler determine the value of NUM_TYPES automagically:
#define NUM_TYPES (sizeof types / sizeof types[0])
static int types[] = {
1,
2,
3,
4 };
#define NUM_TYPES 4
It is also possible to use enumeration.
typedef enum {
typeNo1 = 1,
typeNo2,
typeNo3,
typeNo4,
NumOfTypes = typeNo4
} TypeOfSomething;
As it is already explained in other answers, const in C merely means that a variable is read-only. It is still a run-time value. However, you can use an enum as a real constant in C:
enum { NUM_TYPES = 4 };
static int types[NUM_TYPES] = {
1, 2, 3, 4
};
Imho this is a flaw in many c compilers. I know for a fact that the compilers i worked with do not store a "static const"variable at an adress but replace the use in the code by the very constant. This can be verified as you will get the same checksum for the produced code when you use a preprocessors #define directive and when you use a static const variable.
Either way you should use static const variables instead of #defines whenever possible as the static const is type safe.