468,103 Members | 1,255 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,103 developers. It's quick & easy.

Type safety


In the article http://en.wikipedia.org/wiki/Type_safety

it is written as

The archetypal type-unsafe language is C because (for example) it is
possible for an integer to be viewed as a function pointer, which can
then be jumped to and executed, causing errors such as segmentation
faults, or (more insidiously) silent failures.

Even though the semantics of the C language explicitly allow for these
violations of the type system (indeed, it can be critical for the
performance of operating systems to be written in type-unsafe
languages) the language never defines what should happen when,
for example, a floating-point value is treated as a pointer.

now my question is can anybody give examples/explanations for this

Feb 24 '06 #1
18 1845
El Fri, 24 Feb 2006 09:20:28 -0800, aarklon escribió:

Even though the semantics of the C language explicitly allow for these
violations of the type system (indeed, it can be critical for the
performance of operating systems to be written in type-unsafe
languages) the language never defines what should happen when,
for example, a floating-point value is treated as a pointer.

now my question is can anybody give examples/explanations for this


int main()
{
int a = 0xFFFFFF ;

void (*p)() = (void(*)()) a;
p();

return 0;
}

Feb 24 '06 #2
aa*****@gmail.com wrote:
In the article http://en.wikipedia.org/wiki/Type_safety

it is written as

The archetypal type-unsafe language is C because (for example) it is
possible for an integer to be viewed as a function pointer, which can
then be jumped to and executed, causing errors such as segmentation
faults, or (more insidiously) silent failures.

Even though the semantics of the C language explicitly allow for these
violations of the type system (indeed, it can be critical for the
performance of operating systems to be written in type-unsafe
languages) the language never defines what should happen when,
for example, a floating-point value is treated as a pointer.

now my question is can anybody give examples/explanations for this


Well, the article is a bit misleading. For an unprepared reader it might
create an impression of C language allowing implicit use of an integer
value in a function pointer context, which is not the case. In many
cases one can definitely work around the C type-control system without
using explicit cast (for example, but relying on the implicit "to void*"
and "from void*" pointer conversions), but it is normally not a one-step
process.

The truth is C language merely provides certain means for performing
these violations of the type system. Using these means in the program
still requires a conscious effort from the user in most cases,
especially when it comes to mixing values from the realm of "data" and
values from the realm of "code" (as in the above "integer as function
pointer" example).

--
Best regards,
Andrey Tarasevich
Feb 24 '06 #3
aa*****@gmail.com writes:
In the article http://en.wikipedia.org/wiki/Type_safety

it is written as

The archetypal type-unsafe language is C because (for example) it is
possible for an integer to be viewed as a function pointer, which can
then be jumped to and executed, causing errors such as segmentation
faults, or (more insidiously) silent failures.

Even though the semantics of the C language explicitly allow for these
violations of the type system (indeed, it can be critical for the
performance of operating systems to be written in type-unsafe
languages) the language never defines what should happen when,
for example, a floating-point value is treated as a pointer.


This is largely nonsense. It is not possible to treat an integer as a
function pointer unless you *explicitly* convert it (the result of the
conversion is implementation-defined). The language doesn't allow
conversions from floating-point to poitner types, either implicitly or
explicitly.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Feb 24 '06 #4
On 2006-02-24, Andrey Tarasevich <an**************@hotmail.com> wrote:
aa*****@gmail.com wrote:
In the article http://en.wikipedia.org/wiki/Type_safety

it is written as

The archetypal type-unsafe language is C because (for example) it is
possible for an integer to be viewed as a function pointer, which can
then be jumped to and executed, causing errors such as segmentation
faults, or (more insidiously) silent failures.

Even though the semantics of the C language explicitly allow for these
violations of the type system (indeed, it can be critical for the
performance of operating systems to be written in type-unsafe
languages) the language never defines what should happen when,
for example, a floating-point value is treated as a pointer.

now my question is can anybody give examples/explanations for this


Well, the article is a bit misleading. For an unprepared reader it might
create an impression of C language allowing implicit use of an integer
value in a function pointer context, which is not the case. In many
cases one can definitely work around the C type-control system without
using explicit cast (for example, but relying on the implicit "to void*"
and "from void*" pointer conversions), but it is normally not a one-step
process.

The truth is C language merely provides certain means for performing
these violations of the type system. Using these means in the program
still requires a conscious effort from the user in most cases,
especially when it comes to mixing values from the realm of "data" and
values from the realm of "code" (as in the above "integer as function
pointer" example).


Yeah - And _especially_ in that case, you can't do it by accident - In
fact, it requires syntax that I had to look up: ((int(*)())42)() - and
none of those parentheses are redundant - leave out any pair and it
wont' compile. [well, if you leave out the rightmost pair, it simply
won't attempt to make a function call, i guess] That amount of required
effort to get it to work certainly requires some level of intent.
Feb 24 '06 #5
> The language doesn't allow conversions from floating-point to poitner types, either implicitly or explicitly.

What?

float x = 1.0f;
void *p = *((void**)&x);

Feb 25 '06 #6
ge**********@gmail.com writes:
The language doesn't allow conversions from floating-point to
poitner types, either implicitly or explicitly.


What?

float x = 1.0f;
void *p = *((void**)&x);


There's no conversion from a floating-point to pointer type
there. There's a conversion from pointer-to-float type to
pointer-to-pointer-to-void type. Dereferencing that pointer
doesn't cause a conversion. Typically, it causes
reinterpretation of bits, but its effect is formally undefined as
stated by C99 6.5 "Expressions":

7 An object shall have its stored value accessed only by an
lvalue expression that has one of the following types:73)
- a type compatible with the effective type of the object,
- a qualified version of a type compatible with the
effective type of the object,
- a type that is the signed or unsigned type corresponding
to the effective type of the object,
- a type that is the signed or unsigned type corresponding
to a qualified version of the effective type of the
object,
- an aggregate or union type that includes one of the
aforementioned types among its members (including,
recursively, a member of a subaggregate or contained
union), or
- a character type.

--
"IMO, Perl is an excellent language to break your teeth on"
--Micah Cowan
Feb 25 '06 #7

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
aa*****@gmail.com writes:
In the article http://en.wikipedia.org/wiki/Type_safety

it is written as

The archetypal type-unsafe language is C because (for example) it is
possible for an integer to be viewed as a function pointer, which can
then be jumped to and executed, causing errors such as segmentation
faults, or (more insidiously) silent failures.

Even though the semantics of the C language explicitly allow for these
violations of the type system (indeed, it can be critical for the
performance of operating systems to be written in type-unsafe
languages) the language never defines what should happen when,
for example, a floating-point value is treated as a pointer.
This is largely nonsense. It is not possible to treat an integer as a
function pointer unless you *explicitly* convert it (the result of the
conversion is implementation-defined). The language doesn't allow
conversions from floating-point to poitner types, either implicitly or
explicitly.

One of the design decisions in C was to allow the programmer to examine the
bit representation of data in memory.
It is an inherent property of a digital computer that the bits of any type
can be reinterpreted as any other type.
C does have a few weak protections against the programmer doing this
inadvertently, but they are fairly easy to circumvent. Often it is a good
idea.

For instance, if I know that on my machine ROM routines are from addresses
0x8000 upwards, then by examining the bits of a function pointer I can tell
if it points to a function in RAM or in ROM. That might be useful to know.

--
Buy my book 12 Common Atheist Arguments (refuted)
$1.25 download or $6.90 paper, available www.lulu.com

Feb 25 '06 #8

aa*****@gmail.com wrote:
In the article http://en.wikipedia.org/wiki/Type_safety

it is written as

The archetypal type-unsafe language is C because (for example) it is
possible for an integer to be viewed as a function pointer, which can
then be jumped to and executed, causing errors such as segmentation
faults, or (more insidiously) silent failures.

Even though the semantics of the C language explicitly allow for these
violations of the type system (indeed, it can be critical for the
performance of operating systems to be written in type-unsafe
languages) the language never defines what should happen when,
for example, a floating-point value is treated as a pointer.

now my question is can anybody give examples/explanations for this


Feb 25 '06 #9

"Jordan Abel" <ra*******@gmail.com> wrote in message
news:sl***********************@random.yi.org...
On 2006-02-24, Andrey Tarasevich <an**************@hotmail.com> wrote:
aa*****@gmail.com wrote:
In the article http://en.wikipedia.org/wiki/Type_safety

it is written as

The archetypal type-unsafe language is C because (for example) it is
possible for an integer to be viewed as a function pointer, which can
then be jumped to and executed, causing errors such as segmentation
faults, or (more insidiously) silent failures.

Even though the semantics of the C language explicitly allow for these
violations of the type system (indeed, it can be critical for the
performance of operating systems to be written in type-unsafe
languages) the language never defines what should happen when,
for example, a floating-point value is treated as a pointer.

now my question is can anybody give examples/explanations for this


Well, the article is a bit misleading. For an unprepared reader it might
create an impression of C language allowing implicit use of an integer
value in a function pointer context, which is not the case. In many
cases one can definitely work around the C type-control system without
using explicit cast (for example, but relying on the implicit "to void*"
and "from void*" pointer conversions), but it is normally not a one-step
process.

The truth is C language merely provides certain means for performing
these violations of the type system. Using these means in the program
still requires a conscious effort from the user in most cases,
especially when it comes to mixing values from the realm of "data" and
values from the realm of "code" (as in the above "integer as function
pointer" example).


Yeah - And _especially_ in that case, you can't do it by accident - In
fact, it requires syntax that I had to look up: ((int(*)())42)() - and
none of those parentheses are redundant - leave out any pair and it
wont' compile. [well, if you leave out the rightmost pair, it simply
won't attempt to make a function call, i guess] That amount of required
effort to get it to work certainly requires some level of intent.

But the easy way to treat an integer as a function pointer is to run off the
end of an array, and thus write an integer where a function pointer is
supposed to be.

It's not really about what the standard authorises, it's about what
compilers are able or unable to prevent, by virtue of the language design
and syntax. Strictly conforming C is necessarily type-safe, but the
compiler can't check that code is strictly conforming. In code that's
merely intended to be C, another very easy way to implicitly treat an
integer as a pointer, for instance, is to forget an & when calling scanf.

Undefined behaviour of course, but the point of type safety would be to get
good undefined behaviour -- compilation error or at worst a run-time trap --
rather than bad undefined behaviour.
To get the kind of type safety defined in the article, which comes from an
abstract computer-science perspective, you would have to prevent buffer
overruns, prevent reaching the end of a non-void function, prevent reading
of uninitialised data, keep track of the type associated with dynamic
storage, eliminate variadic functions, etc etc etc.

There are good reasons why C doesn't do this stuff. This is why we like it.
But a few dodgy casts aren't the beginning of C's lack of type safety
(unless you have a much narrower definition of type safety) -- they're just
extras thrown in on the grounds that it's already hopeless so it hardly
matters.
To go back to the OPs request for an example, here's one:

#include <math.h>
struct st {
double x[1];
double (*func)(double);
};
int main (void) {
struct st s;
s.func = sqrt;
s.x[0] = 1.0;
s.x[1] = 33.7; /* bad */
(void)s.func(s.x[0]);
return 0;
}

By writing off the end of the array, I've probably scribbled over the
function pointer, which I then call through, regardless.
Gcc -ansi -pedantic -Wall compiles this without warnings, and there's no
guarantee that the run-time error will be trapped before anything bad
happens.

Granted a smart-enough compiler could catch this simple example, but a more
elaborate example involving multiple translation units and/or run-time
control flow would be essentially uncatchable.

Not earth-shattering news of course, but it's a very general article, and
isn't aiming to tackle the subtleties.

--
RSH


Feb 25 '06 #10
Malcolm wrote:
[ snip ]
One of the design decisions in C was to allow the programmer to examine the
bit representation of data in memory.
It is an inherent property of a digital computer that the bits of any type
can be reinterpreted as any other type.
C does have a few weak protections against the programmer doing this
inadvertently, but they are fairly easy to circumvent. Often it is a good
idea.

For instance, if I know that on my machine ROM routines are from addresses
0x8000 upwards, then by examining the bits of a function pointer I can tell
if it points to a function in RAM or in ROM. That might be useful to know.

How useful? What difference could it make?

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Feb 26 '06 #11
ge**********@gmail.com wrote:
The language doesn't allow conversions from floating-point to poitner types, either implicitly or explicitly.


What?

float x = 1.0f;
void *p = *((void**)&x);


This piece of code does not perform a _conversion_ of floating-point
value to pointer type. What you have here is a _reinterpretation_ of
floating-point lvalue as pointer lvalue (raw memory reinterpretation).
This is a completely different thing in C language world.

For example, in C language _converting_ a pointer of type 'T*' to
'void*' type and back is defined and has its uses. However, trying to
_reinterpret_ a pointer of type 'T*' as a 'void*' pointer (using the
above technique) leads to undefined results. Feel the difference.

The topic of this discussion is _conversions_. What you are implying has
noting to do with conversions.

--
Best regards,
Andrey Tarasevich

Feb 26 '06 #12
On 2006-02-26, Joe Wright <jo********@comcast.net> wrote:
Malcolm wrote:
[ snip ]
One of the design decisions in C was to allow the programmer to examine the
bit representation of data in memory.
It is an inherent property of a digital computer that the bits of any type
can be reinterpreted as any other type.
C does have a few weak protections against the programmer doing this
inadvertently, but they are fairly easy to circumvent. Often it is a good
idea.

For instance, if I know that on my machine ROM routines are from addresses
0x8000 upwards, then by examining the bits of a function pointer I can tell
if it points to a function in RAM or in ROM. That might be useful to know.

How useful? What difference could it make?


Err, so you know if its in ROM or RAM?

--
Remove evomer to reply
Feb 26 '06 #13
In article <46************@individual.net>,
"Richard G. Riley" <rg****@gmail.com> wrote:
On 2006-02-26, Joe Wright <jo********@comcast.net> wrote:
Malcolm wrote:
[ snip ]
One of the design decisions in C was to allow the programmer to examine
the
bit representation of data in memory.
It is an inherent property of a digital computer that the bits of any type
can be reinterpreted as any other type.
C does have a few weak protections against the programmer doing this
inadvertently, but they are fairly easy to circumvent. Often it is a good
idea.

For instance, if I know that on my machine ROM routines are from addresses
0x8000 upwards, then by examining the bits of a function pointer I can
tell
if it points to a function in RAM or in ROM. That might be useful to know.

How useful? What difference could it make?


Err, so you know if its in ROM or RAM?

There are plenty of implementations where a function pointer does _not_
point to the code of a function.
Feb 26 '06 #14
On 2006-02-26, Christian Bau <ch***********@cbau.freeserve.co.uk> wrote:
In article <46************@individual.net>,
"Richard G. Riley" <rg****@gmail.com> wrote:
On 2006-02-26, Joe Wright <jo********@comcast.net> wrote:
> Malcolm wrote:
> [ snip ]
>> One of the design decisions in C was to allow the programmer to examine
>> the
>> bit representation of data in memory.
>> It is an inherent property of a digital computer that the bits of any type
>> can be reinterpreted as any other type.
>> C does have a few weak protections against the programmer doing this
>> inadvertently, but they are fairly easy to circumvent. Often it is a good
>> idea.
>>
>> For instance, if I know that on my machine ROM routines are from addresses
>> 0x8000 upwards, then by examining the bits of a function pointer I can
>> tell
>> if it points to a function in RAM or in ROM. That might be useful to know.
>>
>>
> How useful? What difference could it make?
>


Err, so you know if its in ROM or RAM?

There are plenty of implementations where a function pointer does _not_
point to the code of a function.


It was an example to the somewhat strange question : nothing more. The
OP even qualified with "it *might* be useful to know". In addition if you
are writing HW specifics based on known bit patterns then one would
assume you take into the account what the function pointer is pointing
to wouldnt you?
--
Remove evomer to reply
Feb 26 '06 #15
Richard G. Riley wrote:
On 2006-02-26, Joe Wright <jo********@comcast.net> wrote:
Malcolm wrote:
[ snip ]
One of the design decisions in C was to allow the programmer to examine the
bit representation of data in memory.
It is an inherent property of a digital computer that the bits of any type
can be reinterpreted as any other type.
C does have a few weak protections against the programmer doing this
inadvertently, but they are fairly easy to circumvent. Often it is a good
idea.

For instance, if I know that on my machine ROM routines are from addresses
0x8000 upwards, then by examining the bits of a function pointer I can tell
if it points to a function in RAM or in ROM. That might be useful to know.


How useful? What difference could it make?

Err, so you know if its in ROM or RAM?

And knowing that, how might it change what you would do?

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Feb 26 '06 #16
Joe Wright wrote:
Richard G. Riley wrote:
Joe Wright wrote:
Malcolm wrote:
.... snip ...
For instance, if I know that on my machine ROM routines are from
addresses 0x8000 upwards, then by examining the bits of a function
pointer I can tell if it points to a function in RAM or in ROM.
That might be useful to know.

How useful? What difference could it make?


Err, so you know if its in ROM or RAM?

And knowing that, how might it change what you would do?


It might discourage you from attempting to set a breakpoint there.

--
"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." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Feb 27 '06 #17
Joe Wright <jo********@comcast.net> writes:
Richard G. Riley wrote:
On 2006-02-26, Joe Wright <jo********@comcast.net> wrote:
Malcolm wrote:
[ snip ]

One of the design decisions in C was to allow the programmer to
examine the bit representation of data in memory.
It is an inherent property of a digital computer that the bits of
any type can be reinterpreted as any other type.
C does have a few weak protections against the programmer doing
this inadvertently, but they are fairly easy to circumvent. Often
it is a good idea.

For instance, if I know that on my machine ROM routines are from
addresses 0x8000 upwards, then by examining the bits of a function
pointer I can tell if it points to a function in RAM or in
ROM. That might be useful to know.

How useful? What difference could it make?

Err, so you know if its in ROM or RAM?

And knowing that, how might it change what you would do?


In any of a number of ways, few of which are on-topic here. (For
example, knowing whether a routine is in RAM or ROM might give a clue
about where to look for documentation of the routine, or where to send
bug reports.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Feb 27 '06 #18
On 2006-02-26, Joe Wright <jo********@comcast.net> wrote:
Richard G. Riley wrote:
On 2006-02-26, Joe Wright <jo********@comcast.net> wrote:
Malcolm wrote:
[ snip ]

One of the design decisions in C was to allow the programmer to examine the
bit representation of data in memory.
It is an inherent property of a digital computer that the bits of any type
can be reinterpreted as any other type.
C does have a few weak protections against the programmer doing this
inadvertently, but they are fairly easy to circumvent. Often it is a good
idea.

For instance, if I know that on my machine ROM routines are from addresses
0x8000 upwards, then by examining the bits of a function pointer I can tell
if it points to a function in RAM or in ROM. That might be useful to know.

How useful? What difference could it make?

Err, so you know if its in ROM or RAM?

And knowing that, how might it change what you would do?


Well, I can think of one (OT) immediately : a memory test routine. Why
are you so concerned on why a poster would wish to determine ROM or
RAM? I would say that is their business.

--
Remove evomer to reply
Feb 27 '06 #19

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

12 posts views Thread by Aaron Watters | last post: by
2 posts views Thread by Dave | last post: by
4 posts views Thread by NotYetaNurd | last post: by
3 posts views Thread by karthick.ramachandran | last post: by
27 posts views Thread by Noah Roberts | last post: by
10 posts views Thread by Yevgen Muntyan | last post: by
21 posts views Thread by Chad | last post: by
2 posts views Thread by hcarlens | last post: by
1 post views Thread by Solo | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.