array with a single element

M

maverick

hi,
i came across a code that had the following declaration :

" int tlr_val[1]; "

If i am right the above declares an integer array trl_val having one
element. It could as well be written as "int tlr_val", since we need only 1
element.
Is there any specific purpose behind this kind of declaration ?

thanks,
pcs.
 
L

lallous

maverick said:
hi,
i came across a code that had the following declaration :

" int tlr_val[1]; "

If i am right the above declares an integer array trl_val having one
element. It could as well be written as "int tlr_val", since we need only 1
element.
Is there any specific purpose behind this kind of declaration ?

thanks,
pcs.
Hello

I see such declaration useful in something similar to:

typedef struct
{
char x, y, z;
int tlr_val[1]; // variable length array that belongs to the struct
} theType;

int main()
{
theType *t = (theType *) malloc(sizeof(theType) + (sizeof(int)*(N-1))); //
N: number of elements

t->tlr_val[0, 1,2,3,4,5...N-1] <-- now you can access more than just one
element.
}

HTH,
Elias
 
H

Harti Brandt

On Mon, 19 Jul 2004, lallous wrote:

l>l>> hi,
l>> i came across a code that had the following declaration :
l>>
l>> " int tlr_val[1]; "
l>>
l>> If i am right the above declares an integer array trl_val having one
l>> element. It could as well be written as "int tlr_val", since we need only
l>1
l>> element.
l>> Is there any specific purpose behind this kind of declaration ?
l>>
l>> thanks,
l>> pcs.
l>>
l>Hello
l>
l>I see such declaration useful in something similar to:
l>
l>typedef struct
l>{
l> char x, y, z;
l> int tlr_val[1]; // variable length array that belongs to the struct
l>} theType;
l>
l>int main()
l>{
l> theType *t = (theType *) malloc(sizeof(theType) + (sizeof(int)*(N-1))); //
l>N: number of elements
l>
l> t->tlr_val[0, 1,2,3,4,5...N-1] <-- now you can access more than just one
l>element.
l>}

That's better be done by declaring

struct {
...
int tlr_val[];
};

As for the original question: it could be used to prevent
accidential copying.

harti
 
A

Arthur J. O'Dwyer

On Mon, 19 Jul 2004, lallous wrote:
l>>
l>> " int tlr_val[1]; "
l>> Is there any specific purpose behind this kind of declaration ?
l>
l>I see such declaration useful in something similar to:
l>
l>typedef struct
l>{
l> char x, y, z;
l> int tlr_val[1]; // variable length array that belongs to the struct
l>} theType;

[and then goes on to access tlr_val[n] for n>0]

Note that this is not portable C. It will obviously crash on a
system that does array bounds checking, and possibly on other systems
as well.
That's better be done by declaring

struct {
...
int tlr_val[];
};

(It ought to be noted that this is new in C99, and is an error in
earlier C standards.)
As for the original question: it could be used to prevent
accidential copying.

Or just because we needed an array of one element for some reason,
possibly to pass to or from another function. You /could/ replace
all arrays of one element with single objects, but that would often
murk up the code. Contrived example:

#define TYP_FOO 1
#define TYP_BAR 2
#define TYP_EMPTY 3

int gettype() { return /* pick something */; }
char *getbuffer(int typ);
char *getstring(int typ);

int main()
{
int typ = gettype();
char *buffer = getbuffer(typ);
sprintf(buffer, "%s", getstring(typ));
printf("The result is %s\n", buffer);
}

char *getbuffer(int typ)
{
static char bigbuffer[1000], smallbuffer[100], tinybuffer[1];
switch (typ) {
case TYP_FOO: return bigbuffer;
case TYP_BAR: return smallbuffer;
case TYP_EMPTY: return tinybuffer;
}
}

char *getstring(int typ)
{
switch (typ) {
case TYP_FOO: return "foo";
case TYP_BAR: return "bar";
case TYP_EMPTY: return "";
}
}

HTH,
-Arthur
 
D

Dan Pop

In said:
i came across a code that had the following declaration :

" int tlr_val[1]; "

If i am right the above declares an integer array trl_val having one
element. It could as well be written as "int tlr_val", since we need only 1
element.
Is there any specific purpose behind this kind of declaration ?

Hard to say without more context. Was this declaration alone or part
of a structure definition?

Dan
 
K

karl malbrain

maverick said:
hi,
i came across a code that had the following declaration :

" int tlr_val[1]; "

If i am right the above declares an integer array trl_val having one
element. It could as well be written as "int tlr_val", since we need only 1
element.
Is there any specific purpose behind this kind of declaration ?

Yes. The declaration is easily convertible to parameterization as a pointer
variable. karl m
 
D

Dan Pop

In said:
That's better be done by declaring

struct {
...
int tlr_val[];
};

Something that doesn't even compile on most existing compilers (when
invoked in conforming mode) hardly qualifies as "better".

Dan
 
H

Harti Brandt

On Tue, 20 Jul 2004, Dan Pop wrote:

DP>
DP>>That's better be done by declaring
DP>>
DP>>struct {
DP>> ...
DP>> int tlr_val[];
DP>>};
DP>
DP>Something that doesn't even compile on most existing compilers (when
DP>invoked in conforming mode) hardly qualifies as "better".

Arguing with the number of compilers that support something doesn't really
help because that includes all compilers out of maintenance. I don't think
DECUS C will ever support this. If, for example, there would be just 12 C
compilers - 10 ancient one's which don't support this and which aren't
maintained anymore, and 2 which are maintained and support it, following
your argument would qualify the above as "not better". As far as I know
gcc, icc and Sun's compiler support this - they qualify as 'maintained'.
DECUS C and Whitesmith C don't support [] so the OP would better use [1]
if he writes for a PDP-11. I don't care for Mickeysoft compilers given
their attitude to standards, the OP might however - it's up to him.

harti
 
D

Dan Pop

In said:
On Tue, 20 Jul 2004, Dan Pop wrote:

DP>
DP>>That's better be done by declaring
DP>>
DP>>struct {
DP>> ...
DP>> int tlr_val[];
DP>>};
DP>
DP>Something that doesn't even compile on most existing compilers (when
^^^^
DP>invoked in conforming mode) hardly qualifies as "better".
^^^^^^^^^^^^^^^^^^^^^^^^^^
Arguing with the number of compilers that support something doesn't really
help because that includes all compilers out of maintenance.

By "existing compilers" I mean the ones alive and kicking, not the ones
whose existence is merely a historical fact. Also note the reference to
a conforming mode, that already implies at least C89.
I don't think DECUS C will ever support this.

I don't think DECUS C ever had a conforming mode. Heck, it was not even
conforming to the K&R1 specification...

Dan
 
I

Irrwahn Grausewitz

Harti Brandt said:
On Tue, 20 Jul 2004, Dan Pop wrote:

DP>
DP>>That's better be done by declaring
DP>>
DP>>struct {
DP>> ...
DP>> int tlr_val[];
DP>>};
DP>
DP>Something that doesn't even compile on most existing compilers (when
DP>invoked in conforming mode) hardly qualifies as "better". ^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^

As far as I know
gcc, icc and Sun's compiler support this [...]
^^^
Not if invoked in conforming mode, just as Dan wrote:

D:\Temp>cat foo1.c
struct
{
int foo;
int bar[];
} baz;

D:\Temp>gcc -O -W -Wall -ansi -pedantic -c foo1.c
foo1.c:4: warning: ISO C90 does not support flexible array members

I can't comment on the other compilers, but I doubt they accept above
TU without issuing a diagnostic.

Regards
 
I

Irrwahn Grausewitz

Mark McIntyre said:
gcc, icc and Sun's compiler support this [...]
^^^
Not if invoked in conforming mode, just as Dan wrote:

You have
a) an old version of gcc and/or

Err, no, unless you consider v3.3.1 "old".
b) the wrong flags. Try -c99.

1a. This is about compilers in *conforming* mode. The only C standard
gcc can be made to conform to is ANSI C89 / ISO C90.

1b. If you'd ever used gcc you already know I provided the one and
only correct set of flags to make gcc act as a C compiler:
gcc -O -W -Wall {-ansi|-std=c89} -pedantic

2a. -c99 is AFAIK not a valid gcc command line option; ITYM -std=c99.

2b. If you're looking for a C99 compiler gcc is *not* an option, and
I dare to extrapolate from past release notes that this will be
true for several more years.

Regards
 
D

Dave Thompson

maverick said:
hi,
i came across a code that had the following declaration :

" int tlr_val[1]; "

If i am right the above declares an integer array trl_val having one
element. It could as well be written as "int tlr_val", since we need only 1
element.
Is there any specific purpose behind this kind of declaration ?

Yes. The declaration is easily convertible to parameterization as a pointer
variable. karl m
Amazed as I am to be -- I think -- agreeing with the poster formerly
known as chair:

I worked on one large project which involved a lot (hundreds) of
different struct types containing related bits of data, and spent much
of its effort copying and/or converting fields from one of these to
another. Some instances were "heap" (dynamically) allocated, some
passed by callers using pointers (necessarily when we wanted to modify
them, even potentially, and also in read-only cases for consistency),
and some "stack" (automatic). By making the automatic ones array-of-1,
I could uniformly use pblah->field without frequently having to check
which was which, and without having to recode when something changed
from one form of allocation to another, as happened moderately often.

- David.Thompson1 at worldnet.att.net
 
R

rohitash panda

typedef struct
{
char x, y, z;
int tlr_val[1]; // variable length array that belongs to the struct
} theType;

int main()
{
theType *t = (theType *) malloc(sizeof(theType) + (sizeof(int)*(N-1))); //
N: number of elements

t->tlr_val[0, 1,2,3,4,5...N-1] <-- now you can access more than just one
element.
}

HTH,
Elias
Is this not invoking undefined behaviour ?But it seems to be working
fine on my solaris machine.
 
S

SM Ryan

# > char x, y, z;
# > int tlr_val[1]; // variable length array that belongs to the struct
# >} theType;

# > theType *t = (theType *) malloc(sizeof(theType) + (sizeof(int)*(N-1))); //

# Is this not invoking undefined behaviour ?But it seems to be working
# fine on my solaris machine.

Perhaps, but any implementation that fails to work is going to break so
much code, it would never survive the market. Even if it's given away.

malloc(sizeof(T)*n) will allocate enough room for n elements regardless
of whatever alignment and padding constraints T requires. So the malloc
above will allocate enough space. If there is padding between the last
element and the end of the struct, all that means is it allocates a few
bytes too many and the second array element might overlap padding bytes
that would otherwise be unused.
 

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

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top