473,413 Members | 2,053 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,413 software developers and data experts.

Accessing array elements within a structure

Hi folks,

a simple question for the experts, I guess.

Obviously I am doing something wrong when trying to access an element
of an array declared within a structure:

#include <stdio.h>
#include <stddef.h>

main() {

const int SIZE = 2 ;

struct test {

long type ;
size_t files[SIZE] ;

} ;

struct test example ;

example.type = 100 ;
example.files[0] = 2 ;

printf("type %d - file size %lld:\n", example.type,
example.files[0] ) ;

}

The "intended" output is

type 100 - file size 2:

but I get:

type 100 - file size 12871933952:

(guess I am printing a memory address or something).

What am I doing wrong?

Cheers
Bernd
Jun 27 '08 #1
15 3740

"bernd" <be****@gmx.netwrote in message
news:18**********************************@a1g2000h sb.googlegroups.com...
Hi folks,

a simple question for the experts, I guess.

Obviously I am doing something wrong when trying to access an element
of an array declared within a structure:

#include <stdio.h>
#include <stddef.h>

main() {

const int SIZE = 2 ;

struct test {

long type ;
size_t files[SIZE] ;

} ;

struct test example ;

example.type = 100 ;
example.files[0] = 2 ;

printf("type %d - file size %lld:\n", example.type,
example.files[0] ) ;

}

The "intended" output is

type 100 - file size 2:

but I get:

type 100 - file size 12871933952:

(guess I am printing a memory address or something).

What am I doing wrong?
You're using the wrong 'printf()' format specifier

printf("type %d - file size %lu:\n", example.type,
(unsigned long)example.files[0] ) ;

-Mike
Jun 27 '08 #2
bernd wrote:
Hi folks,

a simple question for the experts, I guess.

Obviously I am doing something wrong when trying to access an element
of an array declared within a structure:

#include <stdio.h>
#include <stddef.h>

main() {

const int SIZE = 2 ;

struct test {

long type ;
size_t files[SIZE] ;

} ;

struct test example ;

example.type = 100 ;
example.files[0] = 2 ;

printf("type %d - file size %lld:\n", example.type,
example.files[0] ) ;

}

The "intended" output is

type 100 - file size 2:

but I get:

type 100 - file size 12871933952:

(guess I am printing a memory address or something).

What am I doing wrong?
Using the "%lld" conversion specifier with a corresponding
argument that is not a `long long int'.

Since you appear to be using a C99 implementation, the
"%zd" specifier ought to work. Or you could use whatever
conversion strikes your fancy, explicitly converting the
`size_t' value to the appropriate type, e.g.

printf ("%d", (int)example.files[0]);

--
Er*********@sun.com

Jun 27 '08 #3
On Mon, 16 Jun 2008 12:44:59 -0400, Eric Sosman wrote:
bernd wrote:
>Hi folks,

a simple question for the experts, I guess.

Obviously I am doing something wrong when trying to access an element
of an array declared within a structure:

#include <stdio.h>
#include <stddef.h>

main() {

const int SIZE = 2 ;

struct test {

long type ;
size_t files[SIZE] ;

} ;

struct test example ;

example.type = 100 ;
example.files[0] = 2 ;

printf("type %d - file size %lld:\n", example.type,
example.files[0] ) ;

}
[...]

Since you appear to be using a C99 implementation, [...]
I'm curious: what makes you think this is a C99 implementation? The
implicit int is specific to C90. The use of a const-qualified object as a
constant expression is specific to C++. The %lld format specifier is
specific to C99, but there's no indication that it's actually supported by
the implementation.
the "%zd" specifier ought to work.
In C99, %zd can be used for the signed type corresponding to size_t, but
there's no standard way to find out what this type is. %zu can be used in
C99 for size_t.

I agree with your and Mike Wahler's suggestions to use a cast, but I
wouldn't recommend either %zd or %zu as an alternative solution without
some more indication that it will actually work.
Jun 27 '08 #4
bernd <be****@gmx.netwrites:
a simple question for the experts, I guess.

Obviously I am doing something wrong when trying to access an element
of an array declared within a structure:

#include <stdio.h>
#include <stddef.h>

main() {

const int SIZE = 2 ;

struct test {

long type ;
size_t files[SIZE] ;

} ;

struct test example ;

example.type = 100 ;
example.files[0] = 2 ;

printf("type %d - file size %lld:\n", example.type,
example.files[0] ) ;

}
The "%d" format requires an argument of type int; you're giving it an
argument of type long (example.type). It happens to "work" for you,
probably because your implementation makes int and long the same size,
but even that doesn't guarantee anything, and it will break on other
implementations.

The "%lld" format requires an argument of type long long; you're
giving it an argument of type size_t (example.files[0]).

It's not sufficient for a format to specify a type that can hold the
value of the corresponding argument, or one that's at least as big as
the argument type, or even that's the same size and signedness. You
have to match the types exactly. (There are some minor exceptions to
this, but they're best ignored; it's easier to match the type exactly
all the time than to remember the circumstances where you can fudge
things a bit.)

In C90, there's no format for size_t. C99 adds "%zu", but you might
not have a C99 implementation (if you did, it would have been required
to issue a diagnostic for your use of implicit int.)

The compiler didn't complain about the mismatch because it's not
required to. The format string is something that exists at run time;
it could have been a variable rather than a string literal. Some
compilers will do some format string checking for you, but in general
you just need to get it right yourself.

Here's how to print those values:

printf("type %ld - file size %lu:\n",
example.type,
(unsigned long)example.files[0]);

That's for C90, and it also works in C99 (as long as the value of
example.files[0] doesn't happen to exceed ULLONG_MAX). Note that the
cast is necessary to ensure that the types match exactly (this is one
of the rare cases where a cast is necesssary and appropriate).

If you're sure your code won't be used with a pre-C99 implementation,
you can do this instead:

printf("type %ld - file size %zu:\n",
example.type,
example.files[0]);

But if you happen to use the above with an implementation that doesn't
support "%zu", it's not required to tell you that it doesn't recognize
the format.

There are some other things you should fix that aren't relevant to
what you were asking about.

"main()" should be "int main(void)". The form you use can work under
some implementations, but "int main(void)" will *always* work
(assuming a hosted implementation rather than a freestanding
implementation).

SIZE is not actually a constant; it's merely a read-only object. This
means that if you use it as an array length, then it's a VLA
(variable-length array). VLAs are not allowed at all in C90, and are
not allowed as structure members even in C99. If the above compiled
without diagnostics, then either you're using a compiler that provides
some sort of extension (and you're invoking it in non-conforming
mode), or you're using a C++ compiler (<OT>in C++ SIZE *is* a
constant</OT>). You can replace your
const int SIZE = 2 ;
with
#define SIZE 2

You should add "return 0;" before the closing '}'. There are
circumstances where it's not necessary, but this is another case where
it's easier to use something that's universally valid than to keep
track of the cases where you can get away with something else. main
returns an int, so you should return an int; 0 is a safe value.

Finally, a style point. I personally dislike white space before a
semicolon. The compiler doesn't care, of course, and some programmers
will disagree with me, but I think most people write semicolons with
no preceding blank.

Here's your program as I would have written it (I've taken the liberty
of changing the output format a bit):

#include <stdio.h>
#include <stddef.h>

int main(void)
{

#define SIZE 2

struct test {
long type;
size_t files[SIZE];
};

struct test example;

example.type = 100;
example.files[0] = 2;

printf("example.type = %ld, example.files[0] = %lu\n",
example.type, (unsigned long)example.files[0]);

return 0;
}

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #5
Harald van Dijk wrote:
On Mon, 16 Jun 2008 12:44:59 -0400, Eric Sosman wrote:
>bernd wrote:
>>Hi folks,

a simple question for the experts, I guess.

Obviously I am doing something wrong when trying to access an element
of an array declared within a structure:

#include <stdio.h>
#include <stddef.h>

main() {

const int SIZE = 2 ;

struct test {

long type ;
size_t files[SIZE] ;

} ;

struct test example ;

example.type = 100 ;
example.files[0] = 2 ;

printf("type %d - file size %lld:\n", example.type,
example.files[0] ) ;

}
[...]
Since you appear to be using a C99 implementation, [...]

I'm curious: what makes you think this is a C99 implementation? The
implicit int is specific to C90. The use of a const-qualified object as a
constant expression is specific to C++. The %lld format specifier is
specific to C99, but there's no indication that it's actually supported by
the implementation.
The variable-length array was the clue I fastened on. The
alternative explanation that he's actually using That Other
Language didn't occur to me (because I have irrational prejudices
about TOL and prefer to think about it as little as possible).
Besides, he couldn't *possibly* be using TOL because if he were
he'd have posted his question in c.l.c++ instead of here, right?
>the "%zd" specifier ought to work.

In C99, %zd can be used for the signed type corresponding to size_t, but
there's no standard way to find out what this type is. %zu can be used in
C99 for size_t.
Right; good catch.

--
Er*********@sun.com
Jun 27 '08 #6
Eric Sosman <Er*********@sun.comwrites:
Harald van Dijk wrote:
>On Mon, 16 Jun 2008 12:44:59 -0400, Eric Sosman wrote:
>>bernd wrote:
[...]
>>> const int SIZE = 2 ;

struct test {

long type ;
size_t files[SIZE] ;

} ;
[...]
>> Since you appear to be using a C99 implementation, [...]
I'm curious: what makes you think this is a C99 implementation? The
implicit int is specific to C90. The use of a const-qualified object
as a constant expression is specific to C++. The %lld format
specifier is specific to C99, but there's no indication that it's
actually supported by the implementation.

The variable-length array was the clue I fastened on.
[...]

C99 doesn't allow VLAs as struct members. C99 6.7.2.1p8:

A member of a structure or union may have any object type other
than a variably modified type.

I note that the original program compiles without diagnostics using
gcc with no options (i.e., in a mode that doesn't conform to any C
standard).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #7
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>I note that the original program compiles without diagnostics using
gcc with no options
And does so even if SIZE is not declared const, and even allows this:

scanf("%d", &SIZE);

struct test2 {
long type ;
size_t files[SIZE] ;
} ;

producing a struct whose size depends on the value of SIZE when the
declaration is encountered.

-- Richard
--
In the selection of the two characters immediately succeeding the numeral 9,
consideration shall be given to their replacement by the graphics 10 and 11 to
facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)
Jun 27 '08 #8
On Jun 16, 10:43 pm, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
In article <lnej6xb8na....@nuthaus.mib.org>,
Keith Thompson <ks...@mib.orgwrote:
I note that the original program compiles without diagnostics using
gcc with no options

And does so even if SIZE is not declared const, and even allows this:

scanf("%d", &SIZE);

struct test2 {
long type ;
size_t files[SIZE] ;
} ;

producing a struct whose size depends on the value of SIZE when the
declaration is encountered.

-- Richard
--
In the selection of the two characters immediately succeeding the numeral 9,
consideration shall be given to their replacement by the graphics 10 and 11 to
facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)
gcc has supported variable length arrays for a long time. Actually
many notable systems(linux kernel) has been written in GNU C. Some of
them has made it to C99(variable length arrays, inline functions).
<off-topic>
Why is it that the structure could not contain variable length arrays?
</off-topic>
Jun 27 '08 #9
rahul <ra*********@gmail.comwrites:
On Jun 16, 10:43 pm, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
>In article <lnej6xb8na....@nuthaus.mib.org>,
Keith Thompson <ks...@mib.orgwrote:
>I note that the original program compiles without diagnostics using
gcc with no options

And does so even if SIZE is not declared const, and even allows this:

scanf("%d", &SIZE);

struct test2 {
long type ;
size_t files[SIZE] ;
} ;

producing a struct whose size depends on the value of SIZE when the
declaration is encountered.
<snip sig>

Best not to quote sig blocks.
gcc has supported variable length arrays for a long time. Actually
many notable systems(linux kernel) has been written in GNU C. Some of
them has made it to C99(variable length arrays, inline functions).
But just in case you or anyone else is confused, *this* kind of
variable length array did *not* get into C99. The form sanctioned by
the standard is to allow the last member of a struct to be an array
with no size size:

struct test {
long type;
size_t files[];
};

-- a formalising of the old "struct hack". Of course, there are other
VLAs in C99 (as automatic storage and as function parameters) which
work differently.

--
Ben.
Jun 27 '08 #10
rahul wrote:
>
.... snip ...
>
gcc has supported variable length arrays for a long time. Actually
many notable systems(linux kernel) has been written in GNU C. Some of
them has made it to C99(variable length arrays, inline functions).
Not if you tell gcc to compile C, rather than the non-standard
gnu-C. This requires using -ansi -pedantic in the command string.
Combined with -W -Wall you will have most portability affecting
source errors exposed.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #11
On Tue, 17 Jun 2008 02:50:50 -0400, CBFalconer wrote:
rahul wrote:
>>
... snip ...
>>
gcc has supported variable length arrays for a long time. Actually many
notable systems(linux kernel) has been written in GNU C. Some of them
has made it to C99(variable length arrays, inline functions).

Not if you tell gcc to compile C, rather than the non-standard gnu-C.
Er... if you tell gcc to compile C, extensions to C90 available in GNU C
will disappear from the C99 standard? Your message does not make sense as
a reply to the text you have quoted. On re-reading, I assume you meant it
as a reply to the first sentence only, but then it's simply wrong. gcc
supports variable-length arrays in C90-conforming mode as well.
Jun 27 '08 #12
Harald van D?k wrote:
CBFalconer wrote:
>rahul wrote:

... snip ...
>>gcc has supported variable length arrays for a long time. Actually
many notable systems(linux kernel) has been written in GNU C. Some
of them has made it to C99(variable length arrays, inline functions).

Not if you tell gcc to compile C, rather than the non-standard gnu-C.
>----------------- elided from qupte ---------------
gnu-C. This requires using -ansi -pedantic in the command string.
Combined with -W -Wall you will have most portability affecting
source errors exposed.
------------------ end of elision -----------------

Er... if you tell gcc to compile C, extensions to C90 available
in GNU C will disappear from the C99 standard? Your message does
not make sense as a reply to the text you have quoted. On re-
reading, I assume you meant it as a reply to the first sentence
only, but then it's simply wrong. gcc supports variable-length
arrays in C90-conforming mode as well.
You snipped a portion of my reply, re-inserted above. Note the
'-ansi' component in the command string. This selects C90/C95 mode
for gcc, not c99 mode. C99 mode requires replacing the '-ansi'
with '-std=C99'.

Please don't snip within paragraphs.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #13
On Wed, 18 Jun 2008 18:17:05 -0400, CBFalconer wrote:
Harald van D?k wrote:
>CBFalconer wrote:
>>rahul wrote:

... snip ...

gcc has supported variable length arrays for a long time. Actually
many notable systems(linux kernel) has been written in GNU C. Some of
them has made it to C99(variable length arrays, inline functions).

Not if you tell gcc to compile C, rather than the non-standard gnu-C.
>>----------------- elided from qupte --------------- gnu-C. This
requires using -ansi -pedantic in the command string. Combined with -W
-Wall you will have most portability affecting source errors exposed.
------------------ end of elision -----------------

Er... if you tell gcc to compile C, extensions to C90 available in GNU
C will disappear from the C99 standard? Your message does not make
sense as a reply to the text you have quoted. On re- reading, I assume
you meant it as a reply to the first sentence only, but then it's
simply wrong. gcc supports variable-length arrays in C90-conforming
mode as well.

You snipped a portion of my reply, re-inserted above.
Yes, I snipped a portion of your reply that I didn't respond to and that
wasn't required to follow my message.
Note the '-ansi'
component in the command string. This selects C90/C95 mode for gcc, not
c99 mode.
Yes, I am aware of that. Notice how I wrote gcc supports variable-length
arrays in C90-conforming mode, and didn't write anything about C99-
conforming mode? You are wrong about C90-conforming mode. gcc, with the
command-line options you gave, supports variable-length arrays.
C99 mode requires replacing the '-ansi' with '-std=C99'.
-std=c99, not C99.
Please don't snip within paragraphs.
I damn well will when it makes the message easier to follow. You decided
not to snip in the paragraph from rahul's message, and that made your
message hard to read.
Jun 27 '08 #14
On 19 Jun 2008 at 5:24, Harald van Dijk wrote:
On Wed, 18 Jun 2008 18:17:05 -0400, CBFalconer wrote:
>Please don't snip within paragraphs.

I damn well will when it makes the message easier to follow.
*blink*

I know CBF would try the patience of a saint, but to provoke Harold
(who usually comes across as a bit like a compiler in human form) to a
display of annoyance is quite an achievement.

We'll know CBF has really made it if he manages to get under the skin of
Chris Torek...

Jun 27 '08 #15
On Mon, 16 Jun 2008 10:06:19 -0700, Keith Thompson <ks***@mib.org>
wrote:
<snip correct and nicely explained diagnosis>
Here's how to print those values:

printf("type %ld - file size %lu:\n",
example.type,
(unsigned long)example.files[0]);

That's for C90, and it also works in C99 (as long as the value of
example.files[0] doesn't happen to exceed ULLONG_MAX). Note that the
(IQC)YM ULONG_MAX.
cast is necessary to ensure that the types match exactly (this is one
of the rare cases where a cast is necesssary and appropriate).
<snip rest>
- formerly david.thompson1 || achar(64) || worldnet.att.net
Jun 27 '08 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Doug C via .NET 247 | last post by:
Using C#... I am pulling shared memory in to my app that is in the form of apredefined structure. I have arrays in 2 sub-structures. Onearray is an array of another predefined structure, and the...
6
by: Chris Styles | last post by:
Dear All, I've been using some code to verify form data quite happily, but i've recently changed the way my form is structured, and I can't get it to work now. Originally : The form is...
22
by: VK | last post by:
A while ago I proposed to update info in the group FAQ section, but I dropped the discussion using the approach "No matter what color the cat is as long as it still hounts the mice". Over the last...
5
by: Joe Thompson | last post by:
Hi I am new to C# and am rewritting some C++ code. I want to send a byte array over a serial port. The elements of the byte array are really a structure I have populated. My question is, how do...
0
by: harsha1305 | last post by:
Hi all, I need to create a pointer to array of structure. Definition of structure: typedef struct { char b_name; unsigned long int sig; unsigned long int count; volatile unsigned char...
38
by: djhulme | last post by:
Hi, I'm using GCC. Please could you tell me, what is the maximum number of array elements that I can create in C, i.e. char* anArray = (char*) calloc( ??MAX?? , sizeof(char) ) ; I've...
2
by: ksarkar | last post by:
I have a problem regarding array of structures within a structure. I have an static array of structure within a structure eg. typedef struct { int x; }A; typedef struct { int...
6
by: Chuck Anderson | last post by:
My knowledge of JavaScript is limited. I learn from example and then adapt those examples to suit my needs. I have stumped myself on this one. I have a form with checkboxes that I want to...
2
by: Opteron64 | last post by:
Hi, I'm trying to create and initialise a dynamic array within a nested structure. The structure is defined as followed: (C++ code) typedef unsigned char uchar; typedef unsigned int uint; ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.