Index out of bounds question

K

Keith Thompson

Tim Rentsch said:
Thank you for pointing out the obvious and failing to respond
to the question.

My pleasure. :cool:}

Sorry, I assumed the question was hypothetical. If you actually need
to worry about pre-ANSI compilers, I'm not sure how much I can help
you (or how much you already know).

There's a tool called "ansi2knr" (google it) that converts, or at
least attempts to convert, ANSI C to K&R C. It doesn't necessarily do
the whole job; I think it deals mainly with function prototypes.

I know K&R C has malloc() returning char* (because it has no void*
type). I don't remember whether it requires a cast when assigning the
result to another pointer type, but I think pre-ANSI compilers tended
to be more permissive about implicit conversions. It also depends on
the compiler; remember, there was no real standard back then.

The obvious brute-force approach is to use "#ifdef __STDC__" and
provide K&R and ANSI versions of any incompatible code. The result is
ugly, but it makes it fairly easy to strip out the K&R stuff if that
requirement finally goes away.

Or you can write pure ANSI code and invoke ansi2knr as part of your
build process. If the result isn't compilable, you might be able to
do some ad-hoc patching, but that might be more effort than it's
worth.

One thing to watch out for is function arguments of types char, short
(and their signed and unsigned variants) and float. In K&R-style
functions, these types are promoted to int or double; in ANSI-style
functions, they're not.

Of course if casting the result of malloc() makes your job easier, go
ahead and do it, perhaps wrapping it in a macro. Just make sure that
<stdlib.h> is included when you compile in ANSI mode.

Your goal, IMHO, should be to move away from the dependency on K&R C
as soon as you can. To state the obvious yet again, it's been 15
years.
 
D

Dan Pop

In said:
How about the case where the code is intended for
both ANSI and pre-ANSI compilers?

If the implementation is pre-ANSI, there may be no malloc() at all in its
library. Even if there is, what is the expected type of its argument?

Your best bet with pre-ANSI compilers is to cast, but this is not going
to solve all your problems. FYI, K&R1 only mentions calloc() and its
companion is called cfree().

These days, in real life projects, you don't have to support more than
one pre-ANSI compiler. In such cases, you simply read its documentation
and see what exactly it says about malloc and about void pointers. Keep
in mind that "pre-ANSI" covers a very wide range of compilers, from those
implementing a subset of the K&R1 specification to those implementing the
same ANSI draft as the one used by the first printing of K&R2.
Just curious - if stdlib.h has been #include'd, can there
still be odd failures when a malloc() return value has
been casted?

Nope. Either the cast is to the right type, and then it is innocuous
from the program correctness point of view or it is to the wrong type
and then a diagnostic is required.

Dan
 
M

Michael Wojcik

How about the case where the code is intended for
both ANSI and pre-ANSI compilers?

Frankly, I'd maintain separate sources, or port a C90 front end
to the environment where I didn't have a standard implementation.
(It could always target the pre-ANSI compiler.)

It's simply not worth giving up all the improvements that C90
brought to K&R C.

If your screwdriver is broken, you don't switch to fastening
everything with duct tape; you get a new screwdriver.
 
T

Tim Rentsch

Herbert Rosenau said:
When the prototype is known to the compiler: No.

That's what I thought but it seemed sensible to double check.

When the prototype is NOT known you lives always in undefined behavior
land - not only for malloc() but with any function returning a
pointer. [more description omitted]

Right. My usual development mode includes at least one compilation
that does strict prototype checking (always require a prototype, don't
allow more than one declaration for any function). Sometimes this
means extra compilations to handle code intended for pre-ANSI
compilers or to allow macro calls to be type checked; but my
experience has been that the extra checking is worth it.

Thanks to Herbert, Ben and Dan (and anyone else I may have forgotten)
who followed up trying to help answer my questions.
 
T

Tim Rentsch

Keith Thompson said:
Your goal, IMHO, should be to move away from the dependency on K&R C
as soon as you can. To state the obvious yet again, it's been 15
years.

Oh, my goal is much broader - to get everyone else to move away from
the dependency on K&R C. :)

As I mentioned in another posting, certain code that I work on forces
me to consider such issues. I don't develop (solely) on pre-ANSI
compilers myself, but in some cases it's important to be able to
provide such code for those poor souls who do.
[ansi2knr, #ifdef __STDC__, wrapping calls to malloc()]

I've used ansi2knr, it's very helpful.

It's necessary on occasion to use things like '#ifdef __STDC__' or
other preprocessor tricks. I don't mind using these tricks but as
much as possible I try to keep them out of mainline code (always
encapsulate). Usually this includes 'malloc()' too (you also
suggested wrapping malloc):

#define ALLOCATE(n,t) ( (t*) malloc( n * sizeof(t) ) )

Of course it doesn't work for some choices of type arguments, but
that's C syntax for you.

Thank you for the other clarifications.
 
T

Tim Rentsch

Tim Rentsch said:
#define ALLOCATE(n,t) ( (t*) malloc( n * sizeof(t) ) )

Of course I meant to write:

#define ALLOCATE(n,t) ( (t*) malloc( (n) * sizeof(t) ) )

I would never leave macro expression-parameters unwrapped
in a publically used macro.
 
D

Dan Pop

In said:
I could envision an implementation that discards bits on
conversion to a pointer type with a bigger-than-byte required
alignment. In general, converting from A* to B* via C* is not
guaranteed to work.

In general, casting to the wrong type by accident *requires* a diagnostic.
The assignment operator involved in a malloc call only converts from
void pointer to the target pointer type.

No way for odd failures to *silently* result.

Dan
 

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

Similar Threads

Out-of-bounds nonsense 63
Fibonacci 0
Adding adressing of IPv6 to program 1
Out-of-bounds Nonsense 7
Bounds Checking as Undefined Behaviour? 29
Queue in C 25
Out-of-bounds Restrictions? 11
Lexical Analysis on C++ 1

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top