If you hate it so much, maybe you should just go use something else?
Because I am demonstrating that C is like a bad slide rule: still
usable because of its triviality.
Boy, that sure would be a lot easier if the function definition had the
contract right next to the code.
No, it wouldn't. Because then I'd have to change it in the function
index at the beginning of the code.
Not to mention a gaping, vast, violation of the spec.
Ooooooooooo
Why, yes.
There's no difference in representation, just in what you're allowed to
try to do using the pointer you get.
But this can be overcome. We shall overcome. Aliasing means that you
can misuse "the pointer you get".
I have no idea what he thinks he means by that. You might be looking at
a C++ book, perhaps, because "const" has extra semantics in C++ that it
lacks in C.
You need to do your homework before you make idiotic mistakes that are
far easier to correct online than C programming errors. You needed
here to look at the book on Amazon. It is not a "C++ book". It is a
comparative study of programming languages and p 111 is about C, not C+
+.
Mostly, though, it seems to me that you are not understanding the distinction
between the pointer and the pointee.
When you declare a "const char *p", you are declaring, not that p is a
constant, but that you cannot modify the things pointed to by p.
What's to prevent me? I do not believe that the compiler is fully able
to prevent me doing this. Because of aliasing the behavior of C code
cannot be determined in full from source.
#include "stdio.h"
void a(const char *p)
{
char *q = p;
*q = ' ';
}
int main()
{
char *p = "1"; a(p);
printf("%c\n", p);
return 0;
}
This code crashes at "*q = ' '" but the compiler fails to detect the
problem. Perhaps there is a compiler that prevents the assignment of
a const pointer to a non-const but in general the compiler cannot
detect all instances of this mistake.
You've been thrown for a loop again by your insistence on using this
"stack" concept where it doesn't apply.
No, you're ignorant of basic CS in which the stack is a basic
explanatory mechanism, because C runtime cannot be implemented without
a stack. Please do NOT step outside your competence.
Or perhaps you'd like to make a real fool of yourself and post a
Vicious Little Tirade about Michael L. Scott and PROGRAMMING LANGUAGE
PRAGMATICS? They'll have a laugh at Morgan Kauffman when they receive
your errata, going after Scott for daring to speak of stacks!
You appear to me to be unread. This is because it is COMMON PRACTICE
to speak of THE STACK as a GIVEN when talking about runtime, because
runtime languages are at a minimum of the Chomsky type that requires
the stack.
What is passed as an argument is an address. Not the contents of the
Please don't waste our time with what we know.
string, but the address of the string. The address passed into the
function is, since C is a pass-by-value language, a "copy" -- of the
address. It points to the same set of characters that were available
elsewhere.
What changes, though, is that because that pointer has a const qualifier
on it, the compiler refuses to accept attempts to modify it.
This refusal is laughably easy to circumvent as I have shown.
Therefore it is folly to expect const to do your thinking for you, as
Fat Bastard seems to think it can.
Contrast this C Sharp code:
class Program
{
static void Main(string[] args)
{
char s = 'a';
a(s);
Console.WriteLine(s);
return;
}
static void a(char s)
{
s = ' ';
}
}
It prints 'a' safely because s is a value parameter and C Sharp
follows the same rule as C (one I think is not a good idea): value
parameters can be modified ON THE STACK (yes the stack). It is not
correct code, but it is safe code.
Correct code is Turing-impossible, but safe code isn't. C has no
concept of what it would be to be safe because the Von Neumann
structure of the machine is visible in C. There is no reason why this
should be the case except in low-level OS functions restricted in
kernel OS design to a small percentage of code. It is vanity,
incompetence and the desire to cover-up real mistakes that drives the
use of C elsewhere.
Managed C Sharp code is in fact provably checked by the compiler for
invalid references to memory as part of the ECMA standard. Your
"standard" normalizes deviance.
So:
void truncate(const char *s) {
s[0] = '\0';
}
If you try to do this, the compiler will (assuming it's working) refuse,
because you're trying to modify something pointed to by s, but the function's
contract says it doesn't modify the stuff pointed to by s.
All I have to do to circumvent it is copy s into a non-const pointer.
OK, does your compiler catch this or not? Perhaps MS should but
doesn't.
Why, certainly.
But if you do, it's undefined behavior, and the compiler can whack you
for it.
Meaning you don't care to define it. Whereas C Sharp defines what
happens if you modify a value parameter, and in C Sharp copying a
string is a sensible and safe operation, not copying a pointer.
Part of maturity in CS and programming is becoming undeluded about
glamorous features than seem to dweebs, naifs and tyros to be "cool".
One of these is the "pointer" which is meaningful only in a von
Neumann architecture and in sensible thinking about computation needs
to be replaced by the concept of a "name".
No one can say.
What it prevents is generating, without actively and intentionally
circumventing the language spec, code which modifies the string to which
you passed a const-qualified pointer. That means that, if you do this,
and then you accidentally write code which tries to modify an argument,
the compiler catches the possible error.
But not all such errors as I have shown you.
The relevance here is to a historical quirk of C, which I don't think anyone
denies is a wart:
The mistake (an American one) is to think that concern with removing
warts is somehow dispensable, secondary, feminine, but here's what
Dijkstra said:
Elegance is not a dispensable luxury but a factor that decides between
success and failure.
* It's undefined behavior to modify the contents of a string literal.
* But they're not const-qualified.
Some compilers have a helpful option which allows you to request them to
The existence of these options, which radically change the language at
compile time, means that C never was standardized in any meaningful
sense, is not standardized today, and never will be standardized.
These options seem to the untutored to be "power" but we have learned
that "power" is weakness when it makes it in fact impossible to safely
describe a language. Any C book will contain "errors" simply because
of C's "flexibility" and these options.
treat string literals as though they were const-qualified. (They aren't,
normally, because a fair amount of existing code would break if they
were changed.)
So imagine that you have two functions:
int length_of_string(const char *s) {
char *end;
for (end = s; *end; ++end)
;
return end - s;
}
void truncate_string(char *s) {
s[0] = '\0';
}
If you use the "string literals are constant" option of a compiler, and
you write:
truncate_string("hello");
you'll get a diagnostic telling you that you can't do that, because
truncate_string can't be called with a const-qualified string. And that
will save you the trouble of wondering why, at runtime, things blew up
when you tried to modify an unmodifiable chunk of data.
No one disputes that this stuff is a bit wonky, and I suspect that if
C had been designed from scratch with "const" fully supported and well
understood, this would likely have gone differently -- most significantly,
string literals would always have been const qualified.
"Knowing mistakes" is not science. It's a form of non-critical
descriptive sociology on a par with stamp collecting and porn.
"Celebrating mistakes" is therefore pretty sleazy and no occupation
for a gentleman.
"Destroying reputations based on the knowledge of mistakes" is
criminal.
Schildt's errors in describing "all possible variants of C", which
wasn't his goal, is nought beside the dishonesty of C programmers,
especially when they use this language except where absolutely
necessary. A managed C sharp program that compiles without errors or
warnings is guaranteed within a six-sigma probability not to cause
memory leaks (except in scenarios I shall describe). This guarantee
cannot be made of C.
It is TRUE of C Sharp that it contains methods that call Windows
systems functions when the library is available. And certain of these
functions will indeed cause memory leaks. For example, I can call MS-
DOS commands by way of a shell and these commands can call C programs
and erase hard disks.
But insofar as I do this, the package delivered cannot be ethically
described as pure .Net no-bullshit C Sharp. Instead it is a Windows
application...that cannot be ported to a non-Windows platform without
change.
But if we contrast C we find that what its mavens call "warts" are in
fact serious errors, so serious that C cannot be sensibly described
with the accuracy we can describe Java or C Sharp applications. It was
therefore vicious folly for you to single out Herb Schildt. The
problem is that C is a corrupted programming language and that you
need to retrain in object oriented languages instead of harassing
Schildt or me. You might get a real programming job if you do so.