Testing if a pointer is valid

R

Rui Maciel

August said:
To me this is the typical macho programmer attitude. We all know that
every programmer makes mistakes every now and then. What sets a safe
programming language apart from an unsafe language is that a program
written in the former is not allowed to proceed executing once it enters
an ill-defined state. This prevents data corruption and makes the error
much easier to find.

This has absolutely nothing to do with "macho programmer attitude", whatever
that is. If a person is employed as a technician, or at least intends to do
work in that field, then the least that person is expected to do is to have
a rudimentary understanding of how the tools of the trade work and what are
the proper ways of using them. If the would-be technician fails to have a
basic understanding how his tools of the trade work then he simply cannot
shift the blame of writing broken code anywhere else beyond his failure of
attaining a basic understanding on how his tools of the trade work, which
includes accusing the tool of being unsafe.

In this case, you tried to claim that C is unsafe by presenting code which
was broken by violating a very basic aspect of how C works, one which is
taught at the very beginning of any introductory course. Yet, even though
the problem with your example lies precisely in an inability to write valid
code, you tried to pass it off as a fundamental problem affecting the entire
programming language. This isn't a sensible thing to do.

If you actually cared for that problem then you would had invested time to
try to understand what were it's causes. This would quickly lead you to the
way an object's lifetime is defined in the C programming language, which
would be enough to understand that the problem resided in the code and not
the language. You could also come to the conclusion that failing to throw a
warning when a local variable is referenced beyond it's life time, or
running similar diagnostics, is a compiler issue, not a language issue.
This is something which has been done before[1]. Yet, you failed to
consider any of this options and instead you opted to accuse the language
of, in a way, being fundamentally broken. This is a problem caused by
nothing more than a willingness to shift blame and responsibilities, not by
"typical macho programmer attitude", and throwing baseless accusations
around does nothing to fix whatever problem there may exist.


Rui Maciel

[1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14156
 
K

Kenny McCormack

This has absolutely nothing to do with "macho programmer attitude", whatever
that is.

This is is priceless. I've seen this sort of phrase a lot lately (on Usenet).

Hint: If you don't know what something is, you can hardly make any
statements about it - including the statement of denial (as above).
If a person is employed as a technician, or at least intends to do
work in that field, then the least that person is expected to do is to have

You need to go back and re-read what I wrote about dynamite.

Again, no one is saying that "unsafe" == bad.
 
R

Rui Maciel

Kenny said:
This is is priceless. I've seen this sort of phrase a lot lately (on
Usenet).

Hint: If you don't know what something is, you can hardly make any
statements about it - including the statement of denial (as above).

You failed to understand what I said. Please read what I've posted in the
message you replied to.

You need to go back and re-read what I wrote about dynamite.

I've already read it. It was a silly comment.

Again, no one is saying that "unsafe" == bad.

If you read what has been said you will realize that the problem with this
assertion is that a piece of broken code is being presented as an example of
how C is supposed to be "unsafe". It's broken code, which a compiler should
consider to be an error or at least throw a warning, something which some
compilers actually do. An entire programming language isn't suddenly deemed
"unsafe" if a compiler fails to run a diagnostic on a specific source of
problems.


Rui Maciel
 
K

Kenny McCormack

Rui Maciel said:
If you read what has been said you will realize that the problem with this
assertion is that a piece of broken code is being presented as an example of
how C is supposed to be "unsafe". It's broken code, which a compiler should
consider to be an error or at least throw a warning, something which some
compilers actually do. An entire programming language isn't suddenly deemed
"unsafe" if a compiler fails to run a diagnostic on a specific source of
problems.

Well, I guess we're just not ever going to go to the prom together.

--
"The anti-regulation business ethos is based on the charmingly naive notion
that people will not do unspeakable things for money." - Dana Carpender

Quoted by Paul Ciszek (pciszek at panix dot com). But what I want to know
is why is this diet/low-carb food author doing making pithy political/economic
statements?

Nevertheless, the above quote is dead-on, because, the thing is - business
in one breath tells us they don't need to be regulated (which is to say:
that they can morally self-regulate), then in the next breath tells us that
corporations are amoral entities which have no obligations to anyone except
their officers and shareholders, then in the next breath they tell us they
don't need to be regulated (that they can morally self-regulate) ...
 
R

Rui Maciel

Keith said:
You almost seem to be implying that only incompetent programmers
make mistakes. I think what you really mean is that only incompetent
programmes make *certain kinds* of mistakes -- but I think that's
unrealistic.

I was referring to the example which was provided to attempt to demonstrate
how unsafe the C programming language was by assigning to a pointer the
reference of a temporary object and expecting to access that object after is
lifetime.

I don't believe it is reasonable to claim that a programming language
suffers from a serious problem by presenting code which is clearly broken
and, by definition, represents an erroneous program construct. The type of
error presented in the example code can only appear in a program if the
programmer who wrote it failed to understand where in a program a specific
object is guaranteed to be accessible. This sort of stuff is so basic that
it's taught right at the start of any C course. As a consequence, trying to
depict such a basic mistake, which is the sole responsible of the programmer
who wrote it, as a major problem affecting a programming language is
simply wrong. At best, complaints may be directed at a compiler for failing
to warn about this issue, but even then this would boil down to a compiler
failing to catch a problem caused by a programmer having written bad code,
and not a issue affecting the programming language.

There are real advantages to languages that make even stupid mistakes
(like using a pointer outside its lifetime) either easy to detect,
or impossible to make in the first place. (And yes, there are also
real advantages to languages like C that give you enough rope to
shoot yourself in the foot, and depend on the programmer to get
things right.)

One example: pre-ANSI C didn't have prototypes, and so compilers
weren't able to diagnose function calls that pass the wrong number
of parameters. I remember running into that when I was first
learning C (coming from a Pascal background), and being horrified.
You could argue (with some justification) that I was incompetent for
writing an incorrect call, but the language design was also partly at
fault for not providing a mechanism to catch such errors. (And the
C committee apparently agreed, and added prototypes to the language.)

The safety of a language is not a simple binary attribute. But a
language (like ANSI C) that diagnoses function calls with the wrong
number of arguments is *safer* than a language (like pre-ANSI C)
that doesn't.

I see what you mean, and you have a point. Nonetheless, some C use cases
tend to be left undefined in order to make it possible for compiler
developers to provide features which otherwise would be in violation of the
C standard. In this specific case, the C standard only defines the portions
of a program where the storage of a specific object is guaranteed to be
reserved. As a consequence, it is up to the compiler developers to specify
how objects are stored in their platform. This means that they are free to
implement anything between eliminating the memory storage right after it is
no longer guaranteed by the C standard and implementing some form of garbage
collection, where malloc/free could effectively be replaced by assigning the
reference of local objects to pointers (which probably would be welcomed by
some embedded developers).

By explicitly defining the limits where a specific behaviour must be
expected then the C standard clearly defines what represents valid C code,
which every competent C programmer is expected to understand. By not
defining what can be expected when programmers intentionally go beyond them,
the C standard grants compiler writers the ability to provide non-portable
features which may be extremely useful in some applications. These non-
portable features, thanks to the way the C standard was defined, are still
considered valid C code, and taking advantage of these platform-specific
features, if they are clearly specified and understood, doesn't force the
code to become broken; only platform-specific.

Another thing which must be taken under consideration is that just because
some behaviour is intentionally left undefined in the C standard it doesn't
mean it must be left undefined in a compiler implementation. This includes
what diagnostics to run and how to react when stumbling on a program
construct which is deemed either erroneous or non-portable by an
implementation. A compiler may throw errors or warnings under these
circumstances if deemed appropriate by the compiler writers, and it is also
possible that the absence of any diagnostic represents a compiler bug. Yet,
the existence/absence of these diagnostics doesn't mean that the language is
suddenly safe/unsafe. This is one of those cases.


Rui Maciel
 
R

Rui Maciel

August said:
Indeed, but my main point was to illustrate that the address-of operator
can lead to a type of undefined behavior that a safe language would not
allow. As I mentioned in a recent post, by a safe language I mean a
language that (at least) prevent invalid memory accesses.

And what leads you to believe that referring to an object past its lifetime,
as defined in the C standard, represents an invalid memory access? This is
behaviour which was intentionally left undefined in the standard. This
means that C compiler writers are free to choose how to implement their
memory management policy as they see fit, which includes explicitly defining
other limits for an object's lifetime. With this, programmers may opt to
strictly follow the behaviour as defined in the C standard, or they may opt
to write non-portable code which takes advantage of the behaviour which has
been defined in a particular platform.

Trying to access objects beyond their lifetime only poses a problem if a
programmer makes the mistake of explicitly relying on behaviour which is
neither defined in the standard nor is supported by the adopted platform.
This is not a problem affecting the C programming language. It's a problem
caused by a clueless programmer writing broken code. Consequently, the
address-of operator clearly doesn't represent a safety risk: only the
programmer does, and only if he doesn't know what he is doing.

It may be argued that the compiler failing to produce a diagnostic message
also contributes to the problem, but this doesn't change the problem's
underlying cause.

Of course not, the word "safe" rather refers to type safety and memory
safety.

If type safety and memory safety is only considered to be at risk due to a
programmer's inability to write valid code which goes against the language
definition then the point is still the same: a programming language cannot
be deemed safe or unsafe due to mistakes made by incompetent programmers.


Rui Maciel
 
R

Rui Maciel

James said:
But the problem you're trying to illustrate occurs only if the lifetime
of the object referred to ends before the reference to it created by
that operator is discarded. That can quite easily happen in C. However,
in languages with a quite different underlying architecture, the object
is guaranteed to continue existing as long as any reference to it
continues to exist.

Just to nitpick, the C standard grants compiler developers the ability to
guarantee just that; that an object continues to exist as long as there is a
reference to it. This is why the C standard specifies the lifetime of an
object as the minimum portion of the program where an object's storage is
guaranteed to exist, why referring to the object outside of it's lifetime is
left undefined, and why the C standard explicitly imposes no requirements on
what value should be stored by any a pointer that points to such an object.

Granted, code which took advantage of this wouldn't be portable, but it
would be valid C code nonetheless.


Rui Maciel
 
N

Nobody

The example you provided represented poorly written code where a pointer
refers to an object after it's lifetime as ended. Understanding an object's
storage duration is very basic stuff. Therefore, this code goes against
extremely basic concepts which are clearly defined and therefore can only be
written by incompetent programmers.

Wrong. Anyone can make mistakes, particularly when working on
poorly-designed and under-documented code with a tight schedule and
limited manpower. Moreso if large sections have incorrect documentation
and no source code.
A programming language cannot be deemed
safe or unsafe due to mistakes made by incompetent programmers.

Actually, this is pretty much the definition of "safe". You can write
correct code in even the most unsafe language. Safety is a question of how
difficult the language makes it to write incorrect code.

Statically-typed languages make it harder to make incorrect assumptions
about the type of a value. Languages with only "managed" pointers make
dangling references impossible. Languages which lack mutable state make
entire classes of bugs impossible.
 
K

Keith Thompson

Rui Maciel said:
Keith Thompson wrote: [...]
The safety of a language is not a simple binary attribute. But a
language (like ANSI C) that diagnoses function calls with the wrong
number of arguments is *safer* than a language (like pre-ANSI C)
that doesn't.

I see what you mean, and you have a point. Nonetheless, some C use cases
tend to be left undefined in order to make it possible for compiler
developers to provide features which otherwise would be in violation of the
C standard. In this specific case, the C standard only defines the portions
of a program where the storage of a specific object is guaranteed to be
reserved. As a consequence, it is up to the compiler developers to specify
how objects are stored in their platform. This means that they are free to
implement anything between eliminating the memory storage right after it is
no longer guaranteed by the C standard and implementing some form of garbage
collection, where malloc/free could effectively be replaced by assigning the
reference of local objects to pointers (which probably would be welcomed by
some embedded developers).

Certainly if I write something simple like:

void func(void) {
int local = 42;
return &local;
}

then I've made a beginner's mistake, and it's probably my own fault,
even though the compiler isn't required to diagnose it.

But I think you're ignoring the fact that many errors are *subtle*. Toy
examples, don't quite illustrate the point, but more realistic examples
are difficult to read.

Bugs are inevitable even in code written by highly skilled and
experienced programmers. Some languages do a better job than others of
helping to diagnose those errors. (C isn't one of those languages, but
there are valid reasons for the tradeoffs C makes.)
By explicitly defining the limits where a specific behaviour must be
expected then the C standard clearly defines what represents valid C code,
which every competent C programmer is expected to understand.
[...]

Understanding the limits is one thing. Consistently avoiding them while
writing or maintaining complex software is quite another.
 
K

Keith Thompson

Rui Maciel said:
If type safety and memory safety is only considered to be at risk due to a
programmer's inability to write valid code which goes against the language
definition then the point is still the same: a programming language cannot
be deemed safe or unsafe due to mistakes made by incompetent programmers.

What about mistakes made by *competent* programmers?
 
K

Keith Thompson

Rui Maciel said:
If you read what has been said you will realize that the problem with this
assertion is that a piece of broken code is being presented as an example of
how C is supposed to be "unsafe". It's broken code, which a compiler should
consider to be an error or at least throw a warning, something which some
compilers actually do. An entire programming language isn't suddenly deemed
"unsafe" if a compiler fails to run a diagnostic on a specific source of
problems.

I'd say that a language that doesn't require a diagnostic for a
particular error is less "safe" than a language that does. It's true
that a particular compiler might warn about it, but that's about the
safety of the compiler, not of the language.
 
P

Phil Carmody

BartC said:
Because he ought to know better.

A true Scotsman might not.
An isolated function could conceivably be called from anywhere. A
macro will always be used in-line in a function where any 'inputs'
might be expected to be already verified or trusted.

I do not share your suppositions.

Phil
 
P

Phil Carmody

Ike Naar said:
We're talking about a pointer to an automatic variable.
Does the lcc-win garbage collector handle those?
Or does it only handle pointers to allocated memory?

And are such pointers "valid" anyway?
If the local variable's out of scope, I would assert that
a pointer to it was no longer valid. Dereferencability has
never been a sufficient condition for being valid, IMHO.

Phil
 
P

Phil Carmody

Willem said:
Rui Maciel wrote:
) Willem wrote:
)
)> Or the language can simply make sure that the pointed-to object keeps
)> existing untill all pointers to it are gone. Which a lot of languages
)> do, actually.
)
) ...or the programmer should be aware that objects do have a life time, and
) it doesn't make sense to write code which refers to objects whose life time
) has passed.

So, either the language takes care of things, or the programmer
should be aware that the language does not take care of things.

Given the average programmer I come across, I prefer the first.

Or, to put it bluntly: in the Real World(tm), most programmers are
a bunch of hacks, who write crap code, so the invention of a language
that takes away responsibility from them is a Good Thing(tm).

And yet even with such languages, people still manage to make
a complete balls-up.

Spikes on steering wheels is the only thing that will improve
driving skills.

Phil
 
P

Phil Carmody

Willem said:
jacob navia wrote:
) Le 20/09/11 22:35, Willem a ?crit :
)>
)> Given the average programmer I come across, I prefer the first.
)>
)> Or, to put it bluntly: in the Real World(tm), most programmers are
)> a bunch of hacks, who write crap code, so the invention of a language
)> that takes away responsibility from them is a Good Thing(tm).
)>
)>
)> SaSW, Willem
)
) What bothers me of those would be managers I have come across (you are

Try again. I'm a maintenance programmer. In other words: I fix the mess
that those hacks leave behind. In the caste system, which you seem so
proud of, I would be ranked lower than them, because I get to clean up
their mess.

So your whole rant falls flat on its face.

Have you also had an appraisal where your manager looks at your
last year's work, and informs you that you had a massively negative
productivity, as measured by lines of code?

I'll never forget the day I stripped out a whole bunch of code
like this, I was laughing all day; crying too, but not sure whether
it was tears of joy or sorrow:

u32 getBit(u32 v, int b)
{
int i;
u32 m=1;
for(i=1; i<b; ++i) {
m<<=1;
}
v&=m;
return v;
}

Phil
 
P

Phil Carmody

Kleuskes & Moos said:
The graduate should have saved his work. Spreadsheets sport a "save"
option for that purpose.

What if whilst trying to populate the pull-down sub-menu
for 'save as', the program dereferenced an uninitialised
pointer that "contained" the non-existent filename!

Phil
 
J

James Kuyper

And are such pointers "valid" anyway?

In C, certainly not. I've no idea whether they're valid in lcc. However,
this branch of this discussion has been about languages with pointers in
general, rather than C or lcc in particular. There's no inherent reason
why a language has to specify that a pointer to an object whose name is
out of scope is invalid; judging from some of the counter examples that
have been provided in this thread, there are some existing languages,
including perl, where such pointers remain perfectly dereferenceable. If
you have a reason why they shouldn't be valid, it would be helpful to
state that reason.

With three decades of programming experience, most of it in C, I find
the concept of such pointers disconcerting - but I don't see any reason
why they shouldn't be allowed.
If the local variable's out of scope, I would assert that
a pointer to it was no longer valid. Dereferencability has
never been a sufficient condition for being valid, IMHO.

As assertion is not as good as an argument. Do you have one?
 
W

Willem

Phil Carmody wrote:
) Have you also had an appraisal where your manager looks at your
) last year's work, and informs you that you had a massively negative
) productivity, as measured by lines of code?

No, we don't do refactoring as it's too expensive, and the whole system
will be scrapped for the next-gen system five years ago.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
K

Kleuskes & Moos

What if whilst trying to populate the pull-down sub-menu for 'save as',
the program dereferenced an uninitialised pointer that "contained" the
non-existent filename!

Kick the testers in the balls. If that didn't show up in testing, someone
hasn't been doing their job.

Besides, populating menus is something that happens in program initialization
(typically), so the user in question did not yet have a chance to write
anything.

-------------------------------------------------------------------------------
_____________________________
< Are you still an ALCOHOLIC? >
-----------------------------
\
\
___
{~._.~}
( Y )
()~*~()
(_)-(_)
-------------------------------------------------------------------------------
 
N

Noob

Robert said:
If Jacob's SNR is 50%, he's still doing better than most here.

Somewhat better than the worst is not very impressive an
achievement... o_O
And unless you're accusing him of something illegal,
"warez" seems a rather inappropriate term.

OK. 20% spammer (peddling his wares).
 

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
474,085
Messages
2,570,597
Members
47,218
Latest member
GracieDebo

Latest Threads

Top