This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Compiler error C247

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

Parents
  • 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.

Reply
  • 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.

Children
  • 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])

    to refer to the number of entries of that array, in, say, a for() loop over it, even from "access.c". But you can't use it in all the same ways you could apply a manifest constant like, say, 1000.

  • 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.