Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Re: How include a large array? (http://www.velocityreviews.com/forums/t959364-re-how-include-a-large-array.html)

Malcolm McLean 04-03-2013 09:25 PM

Re: How include a large array?
 
On Wednesday, April 3, 2013 3:53:39 PM UTC+1, silusi...@gmail.com wrote:
> Hi,
>
> i have this problem: i want to create a large array data that can be portable > and so included in multiple files. I thought about an "array.c" file that
> can be included in test file with an include like this:
>
> #include "array.c"
>
> The compiler gives me an error:why?
>

The error you're going to get with this approach is that the array is declared
twice. However without actually seeing the error message, we can only guess
what went wrong.
>
> I thought about an "array.h" file, but i can't put an instance (in this case the data array) in an header file...or not?
>
> How can i do?
>

The way to do it is to declare the array in array.c, as a global. Then
export the symbol in array.h. This is slightly quirky as you have to be
sure the syntax matches.

silusilusilu@gmail.com 04-04-2013 02:38 PM

Re: How include a large array?
 
Ok,
i'll try to explain better with an example.
i have an array like this:

unsigned char array_v[]={0x01,0x02,0x03};

if i put this array in a file array.c and i use that array in a file foo.c

foo.c

#include "array.c"

....do something...

i have this error from my compiler:
multiple definition of array_v

if i put that array in a file array.h and i do

foo.c
#include "array.h"

....do something...

I have no error. But, if i want to use array_v also in a second file foo2.c

foo2.c
#include "arra.h"

....do something...

i have this error from my compiler:
multiple definition of array_v

John Gordon 04-04-2013 02:50 PM

Re: How include a large array?
 
In <afd1fc85-885a-430d-a4ad-aaddbf740f34@googlegroups.com> silusilusilu@gmail.com writes:

> unsigned char array_v[]={0x01,0x02,0x03};


> if i put this array in a file array.c and i use that array in a file foo.c


> foo.c


> #include "array.c"


> ...do something...


> i have this error from my compiler:
> multiple definition of array_v


Are you compiling both foo.c and array.c into one executable? I.e.
something like this:

cc foo.c array.c -o foo.exe

array.c is already being included in foo.c; you don't need to compile it
at all.

> if i put that array in a file array.h and i do


> foo.c
> #include "array.h"


> ...do something...


> I have no error. But, if i want to use array_v also in a second file foo2.c


> foo2.c
> #include "arra.h"


> ...do something...


> i have this error from my compiler:


> multiple definition of array_v


Again, if you're compiling foo.c and foo2.c as part of the same executable,
then this error will happen. Both foo.c and foo2.c are trying to declare
a global array named "array_v", which you can't do.

--
John Gordon A is for Amy, who fell down the stairs
gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"


Joachim Schmitz 04-04-2013 03:01 PM

Re: How include a large array?
 
silusilusilu@gmail.com wrote:
> Ok,
> i'll try to explain better with an example.
> i have an array like this:
>
> unsigned char array_v[]={0x01,0x02,0x03};
>
> if i put this array in a file array.c and i use that array in a file
> foo.c
>
> foo.c
>
> #include "array.c"
>
> ...do something...
>
> i have this error from my compiler:
> multiple definition of array_v
>
> if i put that array in a file array.h and i do
>
> foo.c
> #include "array.h"
>
> ...do something...
>
> I have no error. But, if i want to use array_v also in a second file
> foo2.c
>
> foo2.c
> #include "arra.h"
>
> ...do something...
>
> i have this error from my compiler:
> multiple definition of array_v


$ cat array.h
#ifdef DEFINE_ARRAY
unsigned char array_v[]={0x01,0x02,0x03};
#else
extern char array_v[];
#endif
$ cat foo.c
#define DEFINE ARRAY /* use this only once */
#include "array.h"
....do something...
$ cat foo2.h
#include "array.h"
....do something...

Bart van Ingen Schenau 04-04-2013 03:18 PM

Re: How include a large array?
 
On Thu, 04 Apr 2013 07:38:05 -0700, silusilusilu wrote:

> Ok,
> i'll try to explain better with an example. i have an array like this:
>
> unsigned char array_v[]={0x01,0x02,0x03};
>
> if i put this array in a file array.c and i use that array in a file
> foo.c
>
> foo.c
>
> #include "array.c"
>
> ...do something...
>
> i have this error from my compiler:
> multiple definition of array_v


This suggests that you both include array.c in foo.c and specify array.c
as a separate source to be compiled.

>
> if i put that array in a file array.h and i do
>
> foo.c
> #include "array.h"
>
> ...do something...
>
> I have no error. But, if i want to use array_v also in a second file
> foo2.c
>
> foo2.c
> #include "array.h"
>
> ...do something...
>
> i have this error from my compiler:
> multiple definition of array_v


The problem you are running into is that, in an entire program, there can
be only one definition of each function or global variable.
This means that the body (for a function) or the initializer (for a
variable) may occur only once in the entire program. And things in header
files are counted each time they are #include-d.

The correct way to use your array is to create both a source *and* a
header file, with the array definition in the source file and a
declaration in the header file, like this:

//file: array.h
#ifndef INCLUDED_ARRAY_H
#define INCLUDED_ARRAY_H

/* declaration of array_v */
extern unsigned char array_v[];

#endif
//eof

//file: array.c
#include "array.h"

/* definition of array_v */
unsigned char array_v[]={0x01,0x02,0x03};

//eof

Bart v Ingen Schenau

Keith Thompson 04-04-2013 03:25 PM

Re: How include a large array?
 
silusilusilu@gmail.com writes:
> i'll try to explain better with an example.
> i have an array like this:
>
> unsigned char array_v[]={0x01,0x02,0x03};
>
> if i put this array in a file array.c and i use that array in a file foo.c
>
> foo.c
>
> #include "array.c"
>
> ...do something...
>
> i have this error from my compiler:
> multiple definition of array_v


[snip]

array.h:
#ifndef ARRAY_H
#define ARRAY_H
extern unsigned char array_v[];
#endif

array.c:
#include "array.h"
unsigned char array_v[]={0x01,0x02,0x03};

main.c:
#include <stdio.h>
#include "array.h"
int main(void) {
printf("array_v: { %d, %d, %d }\n",
array_v[0],
array_v[1],
array_v[2]);
}

Note that this doesn't make the size of array_v visible.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Eric Sosman 04-04-2013 03:32 PM

Re: How include a large array?
 
On 4/4/2013 10:38 AM, silusilusilu@gmail.com wrote:
> Ok,
> i'll try to explain better with an example.
> i have an array like this:
>
> unsigned char array_v[]={0x01,0x02,0x03};
>
> if i put this array in a file array.c and i use that array in a file foo.c
>
> foo.c
>
> #include "array.c"
>
> ...do something...
>
> i have this error from my compiler:
> multiple definition of array_v


You are probably compiling both foo.c and array.c as
separate modules, producing foo.o and array.o (or maybe
foo.obj and array.obj) and linking them into one executable
program. Since both foo.o and array.o define array_v, this
gives you two array_v definitions.

There are many ways to deal with this (because there
are very few restrictions on the content of an #include'd
file), but one of the best is to *define* the array in
array.c, *declare* it in array.h, and include the latter
in foo.c:

/* array.c */
#include "array.h" /* see below */
unsigned char array_v[] = {0x01, 0x02, 0x03};

/* array.h */
extern unsigned char array_v[];

/* foo.c */
#include "array.h" /* not "array.c" */

This is *almost* like writing the definition of array_v
in foo.c itself: foo.c knows that array_v exists and knows
its element type (because array.h declares them), and can go
ahead and use expressions like array_v[i] to access the values.
One important difference: foo.c does not know how big array_v
is, because it's been told of the existence of the array but
not about its size. One way to deal with this (again, there
are many ways) is to define and declare another variable:

/* array.c */
#include "array.h" /* see below */
unsigned char array_v[] = {0x01, 0x02, 0x03};
const unsigned int array_v_length =
sizeof array_v / sizeof array_v[0];

/* array.h */
extern unsigned char array_v[];
extern const unsigned int array_v_length;

/* foo.c */
#include "array.h"

With this arrangement, foo.c now knows that array_v
exists and is an array of unsigned char, and also knows
about the existence of a read-only variable array_v_length.

Now, about that #include "array.h" line in array.c: Why
bother, since it doesn't provide any information that array.c
doesn't already have? It's a safety measure. If you someday
edit array.c and change its content -- maybe you decide to
make array_v_length a size_t instead of an unsigned int --
you might forget to make the corresponding change in array.h.
But if array.c #include's array.h, the compiler will see the
changed and unchanged versions together in one compilation,
will spot the disagreement, and will issue an error message
to draw your attention to the problem.

As I said, that's just one way to do things. It's perhaps
the most common, but another not-too-uncommon situation is
where the array's data is generated by some other program.
You might not want to burden that program with the job of
writing an entire C source file, so you could arrange to have
it just spit out the data values:

0x01, 0x02, 0x03

You'd capture this program's output in a file named something
like array.dat, and then you'd write your array.c as

/* array.c */
#include "array.h" /* as before */
unsigned char array_v[] = {
#include "array.dat"
};
const unsigned int array_v_length =
sizeof array_v / sizeof array_v[0];

If you later decide to change array_v from unsigned char
to unsigned short, you don't need to change and re-run the
helper program: array.dat holds only the values, and doesn't
know or care about the boilerplate you surround them with.

--
Eric Sosman
esosman@comcast-dot-net.invalid


All times are GMT. The time now is 06:36 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.