I have an array defined in a preprocessor statement like that:
#define myArray {0,1,2,3}
When I try to get a value from that array without actually assigning it to a variable first, like so:
myArray[0];
the compiler complains and doesn't let me do that.
This is probably, because this also doesn't work:
{0,1,2,3}[0]
How can I get around this problem? I don't want to use multiple #define statements, and I also don't want to assign the array to a variable in memory first.
Context
I want to implement a patch for an opensource microcontroller project. RAM space is limited, and the whole data flow here is static.
I want to follow the code style in the config file, which uses a lot of array definitions like above.
On the other hand, I don't want to waste RAM space for a useless variable, when it could be done directly.
This can be done with compound literals.
In your case you can do
#define myArray ((int[4]){1,2,3,4})
I would not recommend using compound literals this way. It is unlikely that they are the best solution to your real problem.
#define actually defines a MACRO that the compiler then expands at compilation time to create the executable code that you want.
So you could use:
#define MYARRAY {0,1,2,3}
int testArray[] = MYARRAY;
int element = testArray[0];
but MYARRAY[0] would make no sense to the compiler as there isn't enough information on how the macro should be expanded into executable code, thus it would flag an error.
A word of warning though in the above example the size of testArray isn't determined by the data assigned by the MYARRAY macro, although it will contain the values defined by it, and so the value returned by any sizeof(...) operation may be larger than you expect.
This is from a textbook:
/* This function locates the address of where a new structure
should be inserted within an existing list.
It receives the address of a name and returns the address of a
structure of type NameRec
*/
struct NameRec *linear Locate(char *name)
{
...
}
I understand it returns a pointer to a struct NameRec. Why is "linear" there and why is there a space between "linear" and "Locate"?
#define linear
will make it syntactically correct even if it wasn't before (though, technically, you'd probably want a #undef linear beforehand to avoid possible conflicting macro definitions).
It depends entirely on the context of the code, which you haven't shown. As it stands now, with no header inclusions or definitions like -Dlinear= on the compiler command line, it would not compile in a standards-conformant environment without extensions.
The best way to tell, of course, is to just try to actually compile the thing and see what happens :-)
Given that the solutions link for chapter 13 (the one you're asking about) has no mention of the linear word in the solution, I'd say it's a safe bet to assume your book is incorrect. I'd consider contacting the author (apparently currently working at FDU in New Jersey) to clear it up.
It's a typo in the book. See the locate function here:
https://users.ipfw.edu/chansavj/ACY2017/ANSI_C/ANSI_C_4thEd/Solutions%20to%20Exercises%20(Windows)/Solutions/83556-0s/Ch13/pgm13-5ex3.c
(Posted by ta.speot.is in the comments)
I am not a developer but I understand some C concepts. However, I'm having a hard time finding where the enums (e.g NR_LRU_LISTS, etc) in meminfo.c/meminfo_proc_show() and the variables (e.g. totalram_pages, etc) in page_alloc.c/si_meminfo() are set.
What I meant by set is for example NR_LRU_LISTS = 324077 for instance. What I understood there is that LRU_ACTIVE_FILE equals 3, but there's no = operator in front of NR_LRU_LISTS, so it must be set somewhere else.
I've clicked on the enums/variables to see where they may be called, but there's either too much unrelevant or either non-defining references.
The last thing would be me not being aware of something, but what ?
To be honest, my goal here is to determine how /proc/meminfo 's values are calculated.
But, here my question is: Where do these enums and variables are set ?
Update 1:
The enums part is now solved, and NR_LRU_LISTS equals 5.
But the totalram_pages part seems to be harder to find out...
The constants you are asking about are defined using C's "enum" feature.
enum Foo { A = 4, B, C };
declares constants named A, B, and C with values 4, 5, 6 respectively.
Each constant with no initializer is set to one more than the previous constant. If the first constant in an enum declaration has no initializer it is set to zero.
The variables you are asking about are defined with no initializer, at file scope (that is, outside of any function). For instance, totalram_pages is defined on line 128 of page_alloc.c, with a public declaration for use throughout the kernel on line 50 of linux/mm.h. Because they are defined at file scope and they don't have initializers, they are initialized to zero at program start. (This is a crucial difference from variables defined inside a function with no initializers. Those start off with "indeterminate" values, reading which provokes undefined behavior.)
I do not know how totalram_pages receives a meaningful value. This code is too complicated for me to want to track that down right now.
It sounds like you are just beginning to learn C. Studying other people's code is a good way to learn, but you should start with simple programs. The Linux kernel is not simple, and because it's an operating system kernel, it also does a lot of things that would be considered bad style or just plain wrong in any other program. Don't start with it.
... That said, declaring a bunch of related constants using an enum and letting them take sequential values implicitly is totally normal and good style, and so is defining variables at file scope with no initializer and relying on them to be zero at program start. (It is often wrong to have a global variable in the first place, but if you genuinely need one, relying on implicit initialization to zero is not wrong.) These are things you need to understand and things you are likely to want to do yourself in due course.
(changed name of variable from original question to fit the actual code)
I'm new to C and I'm implementing a queue.
The error is with the static int head=0 variable. It's incremented by 1 each time dequeue() is called. The error seem to occur when the queue is dequeued and function get_person() is called. The head-variable is then as it seems getting a high random number, like 23423449. I have no idea where this comes from. However if I get rid of the "static" keyword so variable is declared as int head=0, it works fine. How come?
using a "global" variable in top of a included file: static int variable1=0
This clearly indicates, that you don't understand what the static keyword means on the global scope. In the global scope, outside of a function, static means, that the variable is visible to only the code within the compilation unit the variable has been defined in.
Now if you define a static variable in a header, each compilation unit that includes that header will have its own variable of that name. So your program is littered with many identically named variables each specific to the compilation unit it's in.
I think what you actually want is an non-static, extern declaration in the header, and exactly one compilation unit actually defining the variable.
I think you are overrunning your person array
One of the strcpy functions is going beyond the bounds of the buffers in the person object, and overwriting the head variable. I would guess the tail and nbr_elem are going too.
You should check that the number of characters you are copying does not exceed the buffer lengths, or use strncpy.
If you declare a global static variable in file A.c, it means this variable is only available within the scope of this A.c file. See : http://en.wikipedia.org/wiki/Static_variable
Since you haven't posted any code, and you are metioning using the same variable in a different file (e.g. B.c), it seems like it is invoking an undefined behavior, which explains the random number your program is printing.
If you wish to use the variable in a different .c file, you should not make it static.
You are calling strcpy without checking that the values you are trying to write will actually fit inside the allocated space inside the person struct.
What is most likely happening is you are writing beyond the allocated memory, and your strcpy is actually overwriting the value of head. strcpy will keep writing until it hits a null terminator ('\0').
If you were to run this in valgrind (a useful tool for finding this type of problem in large programs) it would probably tell you you have invalid writes occurring.
C assumes you know what you are doing, as long as you have access to the memory you can do with it as you please :)
I was asked a question in C last night and I did not know the answer since I have not used C much since college so I thought maybe I could find the answer here instead of just forgetting about it.
If a person has a define such as:
#define count 1
Can that person find the variable name count using the 1 that is inside it?
I did not think so since I thought the count would point to the 1 but do not see how the 1 could point back to count.
Building on #Cade Roux's answer, if you use a preprocessor #define to associate a value with a symbol, the code won't have any reference to the symbol once the preprocessor has run:
#define COUNT (1)
...
int myVar = COUNT;
...
After the preprocessor runs:
...
int myVar = (1);
...
So as others have noted, this basically means "no", for the above reason.
The simple answer is no they can't. #Defines like that are dealt with by the preprocessor, and they only point in one direction. Of course the other problem is that even the compiler wouldn't know - as a "1" could point to anything - multiple variables can have the same value at the same time.
Can that person find the variable name "count" using the 1 that is inside it?
No
As I'm sure someone more eloquent and versed than me will point out #define'd things aren't compiled into the source, what you have is a pre-processor macro which will go through the source and change all instance of 'count' it finds with a '1'.
However, to shed more light on the question you were asked, because C is a compiled language down to the machine code you are never going to have the reflection and introspection you have with a language like Java, or C#. All the naming is lost after compilation unless you have a framework built around your source/compiler to do some nifty stuff.
Hope this helps. (excuse the pun)
Unfortunately this is not possible.
#define statements are instructions for the preprocessor, all instances of count are replaced with 1. At runtime there is no memory location associated with count, so the effort is obviously futile.
Even if you're using variables, after compilation there will be no remnants of the original identifiers used in the program. This is generally only possible in dynamic languages.
One trick used in C is using the # syntax in macros to obtain the string literal of the of the macro parameter.
#define displayInt(val) printf("%s: %d\n",#val,val)
#define displayFloat(val) printf("%s: %d\n",#val,val)
#define displayString(val) printf("%s: %s\n",#val,val)
int main(){
int foo=123;
float bar=456.789;
char thud[]="this is a string";
displayInt(foo);
displayFloat(bar);
displayString(thud);
return 0;
}
The output should look something like the following:
foo: 123
bar: 456.789
thud: this is a string
#define count 1 is a very bad idea, because it prevents you from naming any variables or structure fields count.
For example:
void copyString(char* dst, const char* src, size_t count) {
...
}
Your count macro will cause the variable name to be replaced with 1, preventing this function from compiling:
void copyString(char* dst, const char* src, size_t 1) {
...
}
C defines are a pre-processor directive, not a variable. The pre-processor will go through your C file and replace where you write count with what you've defined it as, before compiling. Look at the obfuscated C contest entries for some particularly enlightened uses of this and other pre-processor directives.
The point is that there is no 'count' to point at a '1' value. It just a simple/find replace operation that happens before the code is even really compiled.
I'll leave this editable for someone who actually really knows C to correct.
count isn't a variable. It has no storage allocated to it and no entry in the symbol table. It's a macro that gets replaced by the preprocessor before passing the source code to the compiler.
On the off chance that you aren't asking quite the right question, there is a way to get the name using macros:
#define SHOW(sym) (printf(#sym " = %d\n", sym))
#define count 1
SHOW(count); // prints "count = 1"
The # operator converts a macro argument to a string literal.
#define is a pre-processor directive, as such it is not a "variable"
What you have there is actually not a variable, it is a preprocessor directive. When you compile the code the preprocessor will go through and replace all instaces of the word 'count' in that file with 1.
You might be asking if I know 1 can I find that count points to it? No. Because the relationship between variables names and values is not a bijection there is no way back. Consider
int count = 1;
int count2 = 1;
perfectly legal but what should 1 resolve to?
In general, no.
Firstly, a #define is not a variable, it is a compiler preprocessor macro.
By the time the main phase of the compiler gets to work, the name has been replaced with the value, and the name "count" will not exist anywhere in the code that is compiled.
For variables, it is not possible to find out variable names in C code at runtime. That information is not kept. Unlike languages like Java or C#, C does not keep much metadata at all, in compiles down to assembly language.
Directive starting with "#" are handled by the pre-processor which usually does text substitution before passing the code to the 'real' compiler. As such, there is no variable called count, it's as if all "count" strings in your code are magically replaced with the "1" string.
So, no, no way to find that "variable".
In case of a macro this is preprocessed and the resulting output is compiled. So it is absolutely no way to find out that name because after the preprocessor finnishes his job the resulting file would contain '1' instead of 'count' everywhere in the file.
So the answer is no.
If they are looking at the C source code (which they will be in a debugger), then they will see something like
int i = count;
at that point, they can search back and find the line
#define count 1
If, however, all they have is variable iDontKnowWhat, and they can see it contans 1, there is no way to track that back to 'count'.
Why? Because the #define is evaluated at preprocessor time, which happens even before compilation (though for almost everyone, it can be viewed as the first stage of compilation). Consequently the source code is the only thing that has any information about 'count', like knowing that it ever existed. By the time the compiler gets a look in, every reference to 'count' has been replaced by the number '1'.
It's not a pointer, it's just a string/token substitution. The preprocessor replaces all the #defines before your code ever compiles. Most compilers include a -E or similar argument to emit precompiled code, so you can see what the code looks like after all the #directives are processed.
More directly to your question, there's no way to tell that a token is being replaced in code. Your code can't even tell the difference between (count == 1) and (1 == 1).
If you really want to do that, it might be possible using source file text analysis, say using a diff tool.
What do you mean by "finding"?
The line
#define count 1
defines a symbol "count" that has value 1.
The first step of the compilation process (called preprocessing) will replace every occurence of the symbol count with 1 so that if you have:
if (x > count) ...
it will be replaced by:
if (x > 1) ...
If you get this, you may see why "finding count" is meaningless.
The person asking the question (was it an interview question?) may have been trying to get you to differentiate between using #define constants versus enums. For example:
#define ZERO 0
#define ONE 1
#define TWO 2
vs
enum {
ZERO,
ONE,
TWO
};
Given the code:
x = TWO;
If you use enumerations instead of the #defines, some debuggers will be able to show you the symbolic form of the value, TWO, instead of just the numeric value of 2.