Why doesn't strrstr() exist?

  • Thread starter Christopher Benson-Manica
  • Start date
D

Douglas A. Gwyn

... They are basically
demanding platform specific, support to make this function safe --

No. If you want to understand what was written, you need to
suppress your preconceptions.
Uh ... excuse me, but dividing by zero has well defined meaning in IEEE
754, and there's nothing intrinsically wrong with it ...

Obviously the fellow meant, as an integer operation.
Anyway, there *is* something intrinsically wrong with it,
or more specifically with trying to integrate infinite
"values" into the real number system.
 
D

Douglas A. Gwyn

Remember IEEE 754 is a specification as well, and unlike the C
specificiation, its generally completely adhered to, and is not
littered with UB.

IEEE 754 was hardly "completely adhered to", and it fails
to specify some things (such as NaN encoding). Also it
was meant from the outset as a spec to be applied to new
implementations of floating-point support, not to cover
existing implementations. Much of C's undefined behavior
is intentional in order to support a wide variety of ISAs
that the C standard is not in a position to constrain.
 
D

Dragan Cvetkovic

Douglas A. Gwyn said:
Anyway, there *is* something intrinsically wrong with it,
or more specifically with trying to integrate infinite
"values" into the real number system.

Why? Its integration into mathematical logic (and analysis) certainly made
a lot of reasoning and proofs easer. C.f. "Nonstandard Analysis" at e.g.
http://mathworld.wolfram.com/NonstandardAnalysis.html or
http://en.wikipedia.org/wiki/Nonstandard_analysis

But "nonstandard C" (in the above sense) wouldn't really work, I guess.

Bye, Dragan

--
Dragan Cvetkovic,

To be or not to be is true. G. Boole No it isn't. L. E. J. Brouwer

!!! Sender/From address is bogus. Use reply-to one !!!
 
D

Douglas A. Gwyn

Its well known that Fortran beats C for numerical applications.

Lots of things are "well known" without being true.
if you take into account that assembly doesn't specify intrinsically
unsafe usages of buffers (like including a gets() function) you could
consider assembly safer ... than C.

Only somebody who is blinded by preconceptions could make
such a ludicrous claim.
But that's all besides the point. I modify my own C usage to beat its
performance by many times on a regular basis (dropping to assembly,
making 2s complement assumptions, unsafe casts between integer types
and pointers etc), and obviously use safe libraries (for strings,
vectors, hashes, an enhanced heap, and so on) that are well beyond the
safety features of C. In all these cases some simple modifications to
the C standard and C library would make my modifications basically
irrelevant.

Because there would be no C implementations except on the
specific platforms to which you limited your code, and
you would force all implementors to provide you with the
specific additional libraries you use. There are good
reasons why the C standards committee doesn't want to do
that.
Making code portable in C requires a lot of discipline, and in truth a
lot of a testing (espcially on numerics, its just a lot harder than you
might think). Its discipline that in the real world basically nobody
has.

The fellow you were responding to already provided one
example of a person with the requisite discipline to use
C safely and effectively. There are many others.

Comparable discipline is needed for any robust software
development process, regardless of the tools used. You
can get away to some extent with relying on tools to
catch some of your sloppiness, but they won't be able to
tell you that you meant x0, not x1 or y0 or whatever you
wrote. Nor is it wise for general-purpose compilers to
try to act as model checkers, etc.
 
D

Douglas A. Gwyn

... I've heard claims that Java is more widely portable, ...

It achieves that by specifying not just the language but
also the data-type representations and object code format.
The down side is that on almost every platform, that
requires simulation of the Java machine architecture.
("Just-in-time" compiling reduces the impact of that.)
C on the other hand was always intended to map directly
onto native hardware operations, such as twiddling bits
in memory-mapped device control registers.
 
R

Randy Howard

(e-mail address removed) wrote
(in article
I've been thinking about this, and there's at least two very different
concepts of portability that might be relevant here, and websnarf is
probably using a different one than you and I.

Most C code is unportable, for one reason or another, and I think
that's what websnarf is thinking of.

Hmmm. If it /is/ C code, then it should be portable. If it is
/sort of/ C code, using a lot of platform extensions that aren't
standard C, then it probably isn't portable, but it can be made
to be portable, with a small amount of extra effort in many
cases.
However, paradoxically, that fact
is directly related to the fact that C is one of the best languages
available for writing code that needs to be portable, which is what I
was thinking of (and I presume you, as well).

Yes, it is. I can't think of any processor-neutral language
available on even a fraction of all the systems for which C is
available.

You do not have to write code that is not portable, although you
may certainly do so. In some cases, it is required. Even then
though, it is possible to use conditional compilation to
generate software that uses platform-specific extensions in part
of the overall source tree yet keeps those exceptions isolated
so that the majority is portable, and adding a new platform to
one of the system-specific modules is minimally painful.
The net result is that it's possible to produce a conforming
implementation of C that is efficient and useful enough to be
profitable, on a wider variety of platforms than would be possible if
the C standard imposed stricter requirements.
Yes.

As a result, you can
count on the presence of a implementation that will accept, translate,
and correctly execute your code on a wider variety of platform than
most other languages.
Of course, that's only true if you're careful enough to avoid writing
unportable C code. I'll concede that it's tricky to write
widely-portable C code, but it's certainly not impossible, or even
unacceptably difficult, to do so.

I agree completely. The problem is, those that only have access
to one, or a few platforms to develop on often have to learn how
the 'hard way', as nothing teaches it faster than the experience
of actually getting your code to compile and work properly on
multiple platforms with fundamental differences in architecture.

For example, anyone that develops primarily on Intel or AMD
based hardware should consider buying a $499 Mac Mini (while
Apple is still shipping PPC) if they think they might have
big-/little-endian issues in their code. It comes with
development tools (including gcc) and from a terminal session
looks pretty much the same as your favorite linux or freebsd
box. If you really care about such things, I can't think of a
more cost-effective way to get a test bed in place to help you
verify the code.
 
K

kuyper

Randy said:
(e-mail address removed) wrote
(in article
<[email protected]>): ....

Hmmm. If it /is/ C code, then it should be portable. If it is

Only if it's strictly conforming C code, which describes a vanishingly
small portion of real C code. Using any standard of conformance less
strict than 'strictly conforming' means that there are platforms it
might not be portable to.

For instance, most of my C code either directly or indirectly calls
many functions that are defined in third-party or system libraris with
names that fall within the namespace reserved for users. Many of those
functions aren't written in strictly conforming C (they are often
written in some other language entirely). That's sufficient to render
my programs non-portable. That's OK because our contract with the
client makes use of those libraries mandatory. Code that's not strictly
conforming for reasons like this one is the norm, not the exception.

....
You do not have to write code that is not portable, although you
may certainly do so. In some cases, it is required. Even then
though, it is possible to use conditional compilation to
generate software that uses platform-specific extensions in part
of the overall source tree yet keeps those exceptions isolated
so that the majority is portable, and adding a new platform to
one of the system-specific modules is minimally painful.

It is possible to use conditional compilation based upon the various
macros defined by the C standard as having implementation-specific
values, to achieve portability. However, if your conditions are
dependent on anything other than those macros, you've probably got a
problem. For instance, the WonderC compiler might specify that it
automatically #defines __WONDERC, and that you should test for this
macro before making use of WonderC extensions. However, there's nothing
in the C standard that prevents the AwfulC compiler from also #defining
__WONDERC, even if it doesn't provide support for WonderC's extensions.
AwfulC could be a perfectly conforming implementation of C, and it
would still be permitted to reject that code, which means that the code
is not strictly conforming. As a practical matter, conditional
compilation based upon such macros is a powerful and effective
technique for making use of implementation-specific features, but
technically it's not guaranteed to work.
 
D

Douglas A. Gwyn

Dragan said:
Why? Its integration into mathematical logic (and analysis) certainly made
a lot of reasoning and proofs easer. ...

It doesn't share in most of the algebraic properties,
sometimes its sign matters and sometimes not, etc. etc.
The latter is even worse in the complex realm where
direction often matters.
 
D

Douglas A. Gwyn

Randy said:
Hmmm. If it /is/ C code, then it should be portable. If it is
/sort of/ C code, using a lot of platform extensions that aren't
standard C, then it probably isn't portable, but it can be made
to be portable, with a small amount of extra effort in many
cases.

Extensions aren't so much the problem as embedding
platform-specific assumptions into the code. It is
good to adopt a general policy of avoiding such
dependencies, but sometimes they are truly necessary.
 
C

Chris Torek

So in this case, how do we "fix" the problem of buffer overflows in C
programs?

I do not know whether this is even possible, much less how "we"
(whoever "we" are in this case) could go about it. I do think that
too many programmers turn to writing C code too soon; languages
that may be "slower" but are "higher level" tend to move the problem
from "dumb" things like buffer overflows (thus eventually executing
arbitrary code) to "smarter" things like allowing people access to
files that were intended to be privileged (thus eventually executing
arbitrary code).

I will, however, note that when I did the 4.2BSD stdio, I attempted
to leave gets() out of the library, or provide one that was annoying
to the programmer; but I was overruled. (I still think this would
have been an appropriate solution. If someone wanted to call gets()
instead of changing the source, it is not that hard to compile with
"cc ... -lgets" -- and it identifies such programs, for later
cleanup. With the BSD makefiles, they would define "LDADD" macros
that included "-lgets".)

[on coroutines]
In any event, I have *studied* coroutines in university, and can
revisit them in far more mainstream languages like Python and Lua. My
understanding of them is not the point (I think I do -- or at least the
"one shot continuation" kind) my point is they should probably be part
of the C standard.

They make a substantial change to the language, in that one must
"wrap up" function state that is, in typical implementations,
destroyed simply by the act of returning from the function. In
particular, one must abandon the idea of a simple linear stack on
which function activation-records are stored. I doubt any one
single entity, no matter how politically or economically powerful,
could push such a change through a future C standard. Perhaps a
group of entities (forming a voting bloc) could do this.

I suspect you would have better luck writing a new language.
 
D

Douglas A. Gwyn

Chris said:
They make a substantial change to the language, in that one must
"wrap up" function state that is, in typical implementations,
destroyed simply by the act of returning from the function. In
particular, one must abandon the idea of a simple linear stack on
which function activation-records are stored. I doubt any one
single entity, no matter how politically or economically powerful,
could push such a change through a future C standard. Perhaps a
group of entities (forming a voting bloc) could do this.

As you say, linguistic support would involve substantial changes,
for relatively minuscule benefit. I'd suggest instead, devising
a platform-independent API for a coroutine library, implementation
of which would necessarily require platform-dependent code if the
coroutines themselves are to be coded as extended C functions.
If such a library worked out well enough, it could be a candidate
for standardization, or at any rate it would be likely to be
widely distributed as are many libraries these days.
 

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
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top