No limits in arrays??

P

Paminu

Is there no such a thing as an ArrayOutOfBounds exception in C?

I just did:

int main()
{
int a[4]; // a is an array that contains 4 integer.
a[5] = 999; // Thought this would give an error!
printf("a[5]: %d\n", a[5]);
return 1;
}

When I run this program

a[5]: 999

gets printed.

How is it possible to put something in a[5] when I have only specified that
a should contain 4 integers?
 
A

AnonMail2005

No such thing in C. The results are undefined. For your compiler and
runtime environment, the program just happened to work.
 
K

Keith Thompson

Paminu said:
Is there no such a thing as an ArrayOutOfBounds exception in C?

I just did:

int main()
{
int a[4]; // a is an array that contains 4 integer.
a[5] = 999; // Thought this would give an error!
printf("a[5]: %d\n", a[5]);
return 1;
}

When I run this program

a[5]: 999

gets printed.

How is it possible to put something in a[5] when I have only specified that
a should contain 4 integers?

This just came up recently.

Accessing an array element beyond the bounds of the array invokes
undefined behavior. This doesn't mean the compiler will detect the
error; it specifically means it's not required to do so. Undefined
behavior can do literally anything; the standard joke is that it can
legally make demons fly out of your nose.

In this case, you're probably just stepping on a memory location past
the end of the array. If the implementation doesn't happen to be
using ithat location for anything, it will most likely not create a
visible error (unfortunately). If it does use it for something, you
might clobber the function's return address or anything else.

The responsibility for avoiding undefined behavior is entirely yours.
Think of C as a power tool without safety features; it's effective
when used properly, but dangerous when used improperly.

Note that accessing a[4] would also invoke undefined behavior; the
valid elements are 0, 1, 2, and 3.
 
K

Keith Thompson

No such thing in C. The results are undefined. For your compiler and
runtime environment, the program just happened to work.

Here we go again.

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

And *please* complain to Google about their broken interface. Search
for occurrences of the above paragraph in this newsgroup; that will
give you an idea of how big a problem it is.
 
K

Kenny McCormack

Here we go again.

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

And *please* complain to Google about their broken interface. Search
for occurrences of the above paragraph in this newsgroup; that will
give you an idea of how big a problem it is.

You are wasting your breath. They'll never get it.
And I'll tell you why.

Imagine that there's a mouse - and the mouse is the Usenet. You and I can
see that it is a mouse and we behave accordingly. But now there is a class
of users (we'll call them "googlers") that are wearing these funny weird
glasses that make them see not a mouse, but an elephant. Seeing an
elephant (i.e., the Usenet as a web page), they also behave accordingly.
And no amount of verbiage from us is going to convince them that it's not
an elephant - that it is only a mouse.

To make this more clear, to a googler, it doesn't make any sense to "quote"
(whatever the heck that is...), in fact, to do would be absurd, when all
the rest of the articles in the thread are right there in front of their
faces (just as clear as the trunk on that mouse, er, elephant). And no
amount of verbiage from us is going to convince them not to believe what
they see. The point is you can *never* convince someone that what they see
isn't reality. The only way you can address the problem is to help them
fix their eyesight (or help them remove their funny glasses).
Keith Thompson (The_Other_Keith) (e-mail address removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

This is a cute line. Where does it come from?
Does it refer to anything beyond the obvious (The obvious being, of course,
the Iraq war) ?
 
M

Markus Moll

Hi
Is there no such a thing as an ArrayOutOfBounds exception in C?

No. And most importantly, there are no exceptions at all in C.
But you're free to write array handling routines that somehow check for
out-of-bounds conditions and report the error... there are probably
libraries around. Something along the lines of

struct array; /* should have members size and data */
array *array_create(size_t size); /* allocate and initialize a new array */
void array_delete(array *me); /* free the array */
int array_at(array *me, size_t pos); /* return value at pos */
void array_set_at(array *me, size_t pos, int value); /* set value at pos */
....

As long as you don't need/use multi-threading, reporting errors through some
errno variable might be enough...

Maybe (although you're asking in a C newsgroup) you would be happier with
C++, as it offers what you seem to be looking for (std::vector<T>::at())?

Markus
 
F

Flash Gordon

Paminu said:
Is there no such a thing as an ArrayOutOfBounds exception in C?

No. Some implementations will trap some out of bounds accesses under
some circumstances, but it is not guaranteed and I'm not aware of any
that will catch all out of bounds accesses.
I just did:

#include said:
int main()
{
int a[4]; // a is an array that contains 4 integer.
a[5] = 999; // Thought this would give an error!
printf("a[5]: %d\n", a[5]);

printf requires a prototype because it is a varidac function, otherwise
that is another point of undefined behaviour. The normal way to provide
the prototype is to include stdio.h

In general, ALWAYS include the headers that define prototypes for the
functions you are using, they are not provided just for the hell of it.
return 1;
}

When I run this program

a[5]: 999

gets printed.

How is it possible to put something in a[5] when I have only specified that
a should contain 4 integers?

On that run there happened to be some memory at the following location.
Don't rely on this, since if you do you will find that you have
overwritten something critical and in the middle of an important demo
that your career depends on (on the result of your course) the program
will do something really annoying like displaying an insulting letter
someone has written about the person you are demonstrating the program to.
 
K

Keith Thompson

You are wasting your breath. They'll never get it.
And I'll tell you why.
[snip]

You've already said this, and I've already explained why I disagree
(speaking of wasting breath).

[...]
This is a cute line. Where does it come from?
Does it refer to anything beyond the obvious (The obvious being, of course,
the Iraq war) ?

I *think* it's originally from "Yes, Minister", a British TV show.
I had one particular thing in mind when I started using it as my
sig quote but it doesn't necessarily refer to anything specific.
And I'm *not* going to discuss politics here.
 
A

Anonymous 7843

Here we go again.

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

And *please* complain to Google about their broken interface. Search
for occurrences of the above paragraph in this newsgroup; that will
give you an idea of how big a problem it is.

I briefly tried out some killfile settings to reduce my
personal noise level in this group. In trn 3.x syntax:

/googlegroups.com/HMessage-ID:j

means to kill any message whose message ID indicates that
it was posted by googlegroups.com. (Other newsreaders should
have similar capabilities.) Anyway, this cuts out quite a
bit of the homework requests, C++ questions, top-postings
and the like.

Having done that, it is immediately clear that there is
another problem: the replies[1] to each google groups post
outnumber the original by about 3:1. Though they are
well-meant (and often well-phrased) exhortations to post
correctly[2], read the FAQ, post in the correct newsgroup, do
your own homework, etc. Still, it becomes tiresome to see
the same concepts repeated. For that,

/googlegroups.com/HReferences:j

brings the noise level down *significantly*. What this does
is to scan for articles which are followups to the google
groups posts, identifying them by their reference to the
original post's message-id, and kills them. This is a bit
non-deterministic: the depth of references that a person's
newsreader preserves upon followup is not consistent. You
aren't just killing immediate followups, but possibly two,
three, or more levels down the article tree.

If the crossposts get to you more than the google groups
posts, you can try out one of these:

/Newsgroups:.*,/h:j
/Newsgroups:.*,.*,/h:j

the first kills any cross-post. The second kills only
crossposts that cross three or more newsgroups. (The
three-way cross-post killer is about the only killfile
entry I have stuck with over the years and across
all newsgroups.)

Of course, the above kill file syntax is ancient, but it
demonstrates that it is possible to quiet the google groups
noise on the receiving end. With some minor effort, it
should be possible to translate the above killfile entries
to something appropriate for your newsreader.

Of course, I'm not sure if this is the optimal approach to
take in this matter. I have two principal concerns:

* Clearly it is unfair to tar all google groups users with
the same brush, but it is also unfair that each of us
should be forced to take on the burden of tarring with a
finer brush.

* Engaging google to fix their broken interface is probably
the kindest approach, but so far no-one has gotten through
to them. Possibly, they have made their decision based on
how other newsgroups behave and are not interested in
special-casing their interface for our benefit.

Sorry, I know this is off-topic meta-discussion, but
hopefully this will make the comp.lang.c experience more
pleasant for some number of people who are as sick of
the google groups noise as I am.

_______
[1] http://www.igopogo.com/pogoplaque.jpg
[2] http://groups.google.com/support/bin/answer.py?answer=14213
 
M

Malcolm Dew-Jones

Flash Gordon ([email protected]) wrote:
: Paminu wrote:
: > Is there no such a thing as an ArrayOutOfBounds exception in C?

: No. Some implementations will trap some out of bounds accesses under
: some circumstances, but it is not guaranteed and I'm not aware of any
: that will catch all out of bounds accesses.

You wouldn't want a compiler to catch all out of bounds errors. A common
idiom for structures is

typedef struct _something
{
struct _something * next;
char data[1];
} something ;

When used, an instance will be malloc'd with a size large enough to
contain your data and then the data member can be accessed as

a_something.data

The array index may commonly appear to be "out of bounds" according to the
definition, but doesn't represent a problem.
 
K

Keith Thompson

Flash Gordon ([email protected]) wrote:
: Paminu wrote:
: > Is there no such a thing as an ArrayOutOfBounds exception in C?

: No. Some implementations will trap some out of bounds accesses under
: some circumstances, but it is not guaranteed and I'm not aware of any
: that will catch all out of bounds accesses.

You wouldn't want a compiler to catch all out of bounds errors. A common
idiom for structures is

typedef struct _something
{
struct _something * next;
char data[1];
} something ;

Leading underscores in identifiers. Ick. (I'm too lazy to check
whether this particular usage is a problem.)
When used, an instance will be malloc'd with a size large enough to
contain your data and then the data member can be accessed as

a_something.data

The array index may commonly appear to be "out of bounds" according to the
definition, but doesn't represent a problem.


It's a common idiom, known as the "struct hack", but strictly speaking
it invokes undefined behavior. A checking implementation could
legally forbid references to any element of a_something.data other
than a_something.data[0].

C99 added a "safe" version of the "struct hack", known as a "flexible
array member". For example:

struct something {
struct something *next;
char data[];
};
 
B

Ben Pfaff

Flash Gordon ([email protected]) wrote:
: Paminu wrote:
: > Is there no such a thing as an ArrayOutOfBounds exception in C?

: No. Some implementations will trap some out of bounds accesses under
: some circumstances, but it is not guaranteed and I'm not aware of any
: that will catch all out of bounds accesses.

You wouldn't want a compiler to catch all out of bounds errors. A common
idiom for structures is

typedef struct _something
{
struct _something * next;
char data[1];
} something ;

There's a FAQ that talks about this.

2.6: I came across some code that declared a structure like this:

struct name {
int namelen;
char namestr[1];
};

and then did some tricky allocation to make the namestr array
act like it had several elements. Is this legal or portable?

A: This technique is popular, although Dennis Ritchie has called it
"unwarranted chumminess with the C implementation." An official
interpretation has deemed that it is not strictly conforming
with the C Standard, although it does seem to work under all
known implementations. (Compilers which check array bounds
carefully might issue warnings.)

Another possibility is to declare the variable-size element very
large, rather than very small; in the case of the above example:

...
char namestr[MAXSIZE];

where MAXSIZE is larger than any name which will be stored.
However, it looks like this technique is disallowed by a strict
interpretation of the Standard as well. Furthermore, either of
these "chummy" structures must be used with care, since the
programmer knows more about their size than the compiler does.
(In particular, they can generally only be manipulated via
pointers.)

C9X will introduce the concept of a "flexible array member",
which will allow the size of an array to be omitted if it is
the last member in a structure, thus providing a well-defined
solution.

References: Rationale Sec. 3.5.4.2; C9X Sec. 6.5.2.1.
 
M

Malcolm Dew-Jones

Keith Thompson ([email protected]) wrote:
: (e-mail address removed) (Malcolm Dew-Jones) writes:
: > Flash Gordon ([email protected]) wrote:
: > : Paminu wrote:
: > : > Is there no such a thing as an ArrayOutOfBounds exception in C?
: >
: > : No. Some implementations will trap some out of bounds accesses under
: > : some circumstances, but it is not guaranteed and I'm not aware of any
: > : that will catch all out of bounds accesses.
: >
: > You wouldn't want a compiler to catch all out of bounds errors. A common
: > idiom for structures is
: >
: > typedef struct _something
: > {
: > struct _something * next;
: > char data[1];
: > } something ;

: Leading underscores in identifiers. Ick. (I'm too lazy to check
: whether this particular usage is a problem.)

"problem"? perhaps that's something new. You (used to) need a name for
the struct but the typedef name is the name you will normally use. I
think I copied the style (underscore on the struct name) from Atari or
Macintosh code.


: > When used, an instance will be malloc'd with a size large enough to
: > contain your data and then the data member can be accessed as
: >
: > a_something.data
: >
: > The array index may commonly appear to be "out of bounds" according to the
: > definition, but doesn't represent a problem.

: It's a common idiom, known as the "struct hack", but strictly speaking
: it invokes undefined behavior. A checking implementation could
: legally forbid references to any element of a_something.data other
: than a_something.data[0].

: C99 added a "safe" version of the "struct hack", known as a "flexible
: array member". For example:

: struct something {
: struct something *next;
: char data[];
: };

Shows how much I use C these days. Thats good to know. I guess I should
bone up on the latest standard (perhaps after learning python and JSP 2).
 
B

Ben Pfaff

Keith Thompson ([email protected]) wrote:
: Leading underscores in identifiers. Ick. (I'm too lazy to check
: whether this particular usage is a problem.)

"problem"? perhaps that's something new. You (used to) need a name for
the struct but the typedef name is the name you will normally use. I
think I copied the style (underscore on the struct name) from Atari or
Macintosh code.

Keith is trying to point out that most identifiers that begin
with an underscore are reserved, so that user code should not use
them. There are some exceptions, but it's really not worth it to
remember them; it's simpler to just never start an identifier
with an underscore.

You can always use a trailing underscore instead.
 
S

S.Tobias

Keith Thompson said:
(e-mail address removed) (Malcolm Dew-Jones) writes:
typedef struct _something
{
struct _something * next;
char data[1];
} something ;

Leading underscores in identifiers. Ick. (I'm too lazy to check
whether this particular usage is a problem.)

I think it's always okay for members.

# -- All identifiers that begin with an underscore and
# either an uppercase letter or another underscore are
# always reserved for any use.
#
# -- All identifiers that begin with an underscore are
# always reserved for use as identifiers with file scope
# in both the ordinary and tag name spaces.
 
P

Paminu

Keith said:
Paminu said:
Is there no such a thing as an ArrayOutOfBounds exception in C?

I just did:

int main()
{
int a[4]; // a is an array that contains 4 integer.
a[5] = 999; // Thought this would give an error!
printf("a[5]: %d\n", a[5]);
return 1;
}

When I run this program

a[5]: 999

gets printed.

How is it possible to put something in a[5] when I have only specified
that a should contain 4 integers?

This just came up recently.

Accessing an array element beyond the bounds of the array invokes
undefined behavior. This doesn't mean the compiler will detect the
error; it specifically means it's not required to do so. Undefined
behavior can do literally anything; the standard joke is that it can
legally make demons fly out of your nose.

In this case, you're probably just stepping on a memory location past
the end of the array. If the implementation doesn't happen to be
using ithat location for anything, it will most likely not create a
visible error (unfortunately). If it does use it for something, you
might clobber the function's return address or anything else.


Ok so I guess my application does not use this memory location since I
always get 999 printed (unless some mysterious coincidence is taken place).
 
F

Flash Gordon

S.Tobias said:
Keith Thompson said:
(e-mail address removed) (Malcolm Dew-Jones) writes:
typedef struct _something ^^^^^^^^^^
{
struct _something * next;
char data[1];
} something ;

Leading underscores in identifiers. Ick. (I'm too lazy to check
whether this particular usage is a problem.)

I think it's always okay for members.

Maybe, but this was not a member, it was a tag.
# -- All identifiers that begin with an underscore and
# either an uppercase letter or another underscore are
# always reserved for any use.
#
# -- All identifiers that begin with an underscore are
# always reserved for use as identifiers with file scope
# in both the ordinary and tag name spaces.

So if it was at file scope, which is likely since it looks like the
typedef for a linked list, it does fall foul of this.

As Keith said, it is simplest to just avoid all leading underscores and,
IMHO, it was a mistake for the standard to make the rules this complex.
 
K

Keith Thompson

Keith Thompson ([email protected]) wrote:
: (e-mail address removed) (Malcolm Dew-Jones) writes: [...]
: > You wouldn't want a compiler to catch all out of bounds errors. A common
: > idiom for structures is
: >
: > typedef struct _something
: > {
: > struct _something * next;
: > char data[1];
: > } something ;

: Leading underscores in identifiers. Ick. (I'm too lazy to check
: whether this particular usage is a problem.)

"problem"? perhaps that's something new. You (used to) need a name for
the struct but the typedef name is the name you will normally use. I
think I copied the style (underscore on the struct name) from Atari or
Macintosh code.

Others have explained the problem with leading underscores.

In addition to that, there's really no need for the typedef. The
struct tag is all you need. For example (using C99 syntax for the
flexible array member):

struct something {
struct something *next;
char data[];
};

struct something s;
struct something *p;

The typedef can save you a few keystrokes (which is *not* necessarily)
a good thing). It also hides the fact that the type is a struct,
something that you don't usually want to hide (though there are
exceptions).

This is a matter of style, and not everyone agrees.
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top