We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello all, I have the following situation and error message that I'm not quite able to wrap my head around. I have a module, let's call it table.c that has something like the following. code const entry_type table[] = {...}; code const unsigned int tablesize = sizeof(table); Of course, ... is replaced by a bunch of table data. In another module, call it access.c, I have the following: extern code const entry_type table[]; extern code const unsigned int tablesize; code const unsigned int entrysize = sizeof(entry_type); code const unsigned int numentries = tablesize/entrysize; I receive an error C247 when trying to compile the line where I calculate numentries. Oddly enough, it doesn't complain about calculating entrysize, so it's good with making that a code constant. Nor does it have a problem in table.c creating the tablesize code constant. I'm not sure why then it wouldn't think that numentries could be a code constant. I've also tried making sure that table.c is compiled before access.c (just a blind attempt) and that didn't help. Any help would be greatly appreciated. Best Regards, Jay Daniel
Only the linker will when it links them. So, sizeof called from access.c just returns 0 which isn't of much value to me Exactly. So don't do that. Call sizeof on this array only from the module that does know its size, not from others modules that don't. In other words: move the declaration and definition of numentries into the header/module that holds your table, and all will be well. That's where this constant belonged right from the start, too. The number of entries of your table is a fundamental aspect of the array itself, so there's not much point defining it outside the module that holds the table itself. Actually, you could more sensibly remove tablesize from the interface of table.c: no other module should really have to know that. On a more abstract ground, you're probably over-doing the modularization anyway: accessing an array is an integral part of it being an array, so "access.c" should not be a separate module.
Hans-Bernhard, Thanks for your comments. The actual reason I'm doing this isn't for abstraction and modularization. It's because I'm linking to another source tree to get some information about data structures in use on that system. Also, the array.c and access.c modules were just to illustrate the problem. They're not the actual code. Perhaps a better way to pose this question would be like this: Imagine I only have access to the object output from table.c and can't modify the code. I know that the code defines these tables, I have the structure of each entry, and I know that there are code constants for the size in bytes. Given that information, is there any other way in access.c that I could create code constants for the number of entries?
Given that information, is there any other way in access.c that I could create code constants for the number of entries? Not if you want to use it to e.g. initialize variables with static duration or size arrays with it. A const variable declared by a header file, with its definition found elsewhere, doesn't qualify as a "constant" for the purposes of C programming, because it's not known at compile time. Only the linker knows the value or even actual address of such a variable, but by the time the linker runs, it's too late. You could use the expression
tablesize / sizeof(table[0])
it is actually dead simple in a .h file everybody include #define ARRAY_SIZE 123 in the file with the array arrayname[ARRAY_SIZE] Erik
Hans-Bernhard, Thanks for the explanation. I actually wanted some way to size another array to match it, but have resigned my self to working around this another way. I figured it was worth asking though.