Code organization / initialize global array

A

André Hänsel

Hi,

in a small project at the moment my code is organized like this:
- All .c files include headers.h
- headers.h includes all .h files

Now I wanted to add an array by adding an .h file:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},
....

But then I get an error:
Entry "ASCII_to_Scancode" in module main redefined in module ports

How do I organize my code in the right way?

Regards,
André
 
B

Ben Bacarisse

André Hänsel said:
in a small project at the moment my code is organized like this:
- All .c files include headers.h
- headers.h includes all .h files

Hmmm... that's not the most helpful way to do it. I'm guessing you
don't use something like "make" or you would not want to do this. It is
generally better to include just those headers that are needed by each
..c file. You can also include one .h inside another if everything that
must include the one must also include the other. Opinions differ about
the merits of that approach.
Now I wanted to add an array by adding an .h file:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},
...

But then I get an error:
Entry "ASCII_to_Scancode" in module main redefined in module ports

How do I organize my code in the right way?

You should put the array definition if the .c file in which it seems to
belong (or, I suppose, in its own if there is no logical place for it).
The header file should contain only an external declaration for the
array.

Better yet, define the operations that use the table and export only the
function prototypes. I.e. make the table static in a .c file that
defines the functions that use it. There will be corresponding
prototypes in a header file.
 
V

Vincenzo Mercuri

André Hänsel ha scritto:
Hi,

in a small project at the moment my code is organized like this:
- All .c files include headers.h
- headers.h includes all .h files

Now I wanted to add an array by adding an .h file:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},
...

But then I get an error:
Entry "ASCII_to_Scancode" in module main redefined in module ports

How do I organize my code in the right way?

Regards,
André

Hi,
can you reproduce the smallest example of code that
leads to the same error?
It seems like a 'extern' is missing, or ..?
 
A

André Hänsel

Hmmm... that's not the most helpful way to do it.  I'm guessing you
don't use something like "make" or you would not want to do this.  It is
generally better to include just those headers that are needed by each
.c file.  You can also include one .h inside another if everything that
must include the one must also include the other.  Opinions differ about
the merits of that approach.

Well, the project only consists of 5 C files, but I'll bear that in
mind.
Now I wanted to add an array by adding an .h file:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
   {0x45,0xF0,0x45,0x00},
   {0x45,0xF0,0x45,0x00},
...
But then I get an error:
Entry "ASCII_to_Scancode" in module main redefined in module ports
How do I organize my code in the right way?

You should put the array definition if the .c file in which it seems to
belong (or, I suppose, in its own if there is no logical place for it).
The header file should contain only an external declaration for the
array.

Oh yes, I was missing the "extern".
Better yet, define the operations that use the table and export only the
function prototypes.  I.e. make the table static in a .c file that
defines the functions that use it.  There will be corresponding
prototypes in a header file.

This is how I worked around the problem, but I have only 2K of ROM, so
I'm happy to save the function. ;)
 
D

Dean

Hi,

in a small project at the moment my code is organized like this:
- All .c files include headers.h
- headers.h includes all .h files

Now I wanted to add an array by adding an .h file:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},
....

But then I get an error:
Entry "ASCII_to_Scancode" in module main redefined in module ports

How do I organize my code in the right way?

Regards,
André

In the .h file:

extern const char ASCII_to_Scancode[256][max_number_of_scancodes_per_character];

In a single .c file:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},
....

Or better yet, don't use global variables
 
T

Tim Rentsch

Dean said:
[snip]

In the .h file:

extern const char ASCII_to_Scancode[256][max_number_of_scancodes_per_character];

In a single .c file:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},
....

Or better yet, don't use global variables

Do you mean to condemn global data objects even when (like
the array here) they are 'const'?
 
N

Nick Keighley

Dean said:
In the .h file:
extern const char ASCII_to_Scancode[256][max_number_of_scancodes_per_character];
In a single .c file:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
       {0x45,0xF0,0x45,0x00},
       {0x45,0xF0,0x45,0x00},
....
Or better yet, don't use global variables

Do you mean to condemn global data objects even when (like
the array here) they are 'const'?

er, yes. They still introduce unnecessary coupling
 
T

Tim Rentsch

Nick Keighley said:
Dean said:
In the .h file:
extern const char ASCII_to_Scancode[256][max_number_of_scancodes_per_character];
In a single .c file:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},
....
Or better yet, don't use global variables

Do you mean to condemn global data objects even when (like
the array here) they are 'const'?

er, yes. They still introduce unnecessary coupling

This statement has no useful semantic content. It is of course
possible to define 'necessary' in such a way that any coupling of
type X is 'unnecessary', but that doesn't tell us anything of
interest, any more than (for example) saying "'for()', 'while()',
and 'switch()' are all unnecessary". The question is, does using
a constant global data object represent a reasonable design
choice amongst the plausible alternatives? Whether it does
depends not only on the amounts and kinds of coupling between
different modules but also on what the other tradeoffs are
between the various alternatives.
 
R

Richard Bos

Dean said:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},

Or better yet, don't use global variables

This isn't a variable, it is a lookup table. There is no reason for it
to change during the run of the program. That is one of the cases in
which the use of a global array is entirely justifiable.

Richard
 
B

Barry Schwarz

Dean said:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},

Or better yet, don't use global variables

This isn't a variable, it is a lookup table. There is no reason for it
to change during the run of the program. That is one of the cases in
which the use of a global array is entirely justifiable.

The standard refers the such declared objects as variables fairly
often. It seems an appropriate use of the term even if the comment is
not.
 
K

Keith Thompson

Barry Schwarz said:
Dean said:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},

Or better yet, don't use global variables

This isn't a variable, it is a lookup table. There is no reason for it
to change during the run of the program. That is one of the cases in
which the use of a global array is entirely justifiable.

The standard refers the such declared objects as variables fairly
often. It seems an appropriate use of the term even if the comment is
not.

No, it doesn't. The standard uses the term "variable" to refer to
declared objects only in a handful of places in non-normative text;
none of those are const-qualified.
 
B

Barry Schwarz

Barry Schwarz said:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},

Or better yet, don't use global variables

This isn't a variable, it is a lookup table. There is no reason for it
to change during the run of the program. That is one of the cases in
which the use of a global array is entirely justifiable.

The standard refers the such declared objects as variables fairly
often. It seems an appropriate use of the term even if the comment is
not.

No, it doesn't. The standard uses the term "variable" to refer to
declared objects only in a handful of places in non-normative text;
none of those are const-qualified.

I wasn't aware that a term had to appear in the normative part of the
text in order to indicate it was acceptable in discussions about the
language. If so, then sections 7.6 and F.8.1 are twice as many as
needed to satisfy that condition.

Since a const-qualified object can also be volatile-qualified
(6.2.5-26 and 6.5.15-8), it seems apparent that const does not mean
the value of the object can never change. So even if the object
cannot be called a variable, it certainly can be variable. Objections
to the noun seem somewhat artificial.
 
K

Keith Thompson

pete said:
I just noticed that the C99 standard
has the phrase "global variables" in normative text.

Are you seeing something I'm not, or did you omit a "does not"?
 
K

Keith Thompson

Barry Schwarz said:
Barry Schwarz said:
const char ASCII_to_Scancode[256]
[max_number_of_scancodes_per_character] = {
{0x45,0xF0,0x45,0x00},
{0x45,0xF0,0x45,0x00},

Or better yet, don't use global variables

This isn't a variable, it is a lookup table. There is no reason for it
to change during the run of the program. That is one of the cases in
which the use of a global array is entirely justifiable.

The standard refers the such declared objects as variables fairly
often. It seems an appropriate use of the term even if the comment is
not.

No, it doesn't. The standard uses the term "variable" to refer to
declared objects only in a handful of places in non-normative text;
none of those are const-qualified.

I wasn't aware that a term had to appear in the normative part of the
text in order to indicate it was acceptable in discussions about the
language.

It doesn't, and I didn't mean to imply that it does.
If so, then sections 7.6 and F.8.1 are twice as many as
needed to satisfy that condition.

7.6 and F.8.1 refer to floating-point status flags and floating-point
control modes, not C objects, as "system variables".

(BTW, by my count there are 8 uses of the noun "variable" in the C99
standard referring to C objects, all of them in non-normative text.
I won't dispute whether this qualifies as "fairly often".)
Since a const-qualified object can also be volatile-qualified
(6.2.5-26 and 6.5.15-8), it seems apparent that const does not mean
the value of the object can never change. So even if the object
cannot be called a variable, it certainly can be variable. Objections
to the noun seem somewhat artificial.

My only objection to the term "variable" is that it's imprecise.
A declared object that's not const qualified is, I'd say,
unambiguously a "variable", and I have no problem calling it that.
Any other object might or might not be, depending on who's defining
the term.

In this particular case, I personally wouldn't refer to
ASCII_to_Scancode as a "variable", simply because it's const-qualified
and therefore does not vary (in spite of the old "constants aren't,
variables won't" joke).

But if you want to call it a variable, the standard offers me no
basis to refute you.
 
K

Keith Thompson

Ben Bacarisse said:
F.8.1 p1. The phrase is split across a line.

Yes, that's the one, thanks. Not sure how I missed that (I even
searched for just "global").
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,174
Latest member
BlissKetoACV
Top