Question about the clc string lib

M

Michael Wojcik

Can I #undef it and then #define my own?

It's my understanding that this invokes undefined behavior. Whether
it's a problem for any actual existing implementation is another
question, of course.
It seems like this would fall
into the same dubious area as redefining a keyword, but would still be
legal (just as it is to redefine a keyword)

Redefining a keyword is only "legal" because they're only reserved
in translation phases 7 and 8 (C99 6.4.1#2). (This is a "shall"
requirement, so violating it causes UB, by 4#2.) Since macros are
expanded in translation phase 4, by the time phase 7 is reached,
macros that have the same names as keywords (eg "#define if foo")
no longer appear as identifiers in the translation unit.

No such special rule exists for other reserved identifiers, as far
as I can see.
 
J

Jeff

CBFalconer said:
Strings of length approaching SIZE_MAX are so common in my code
that I worry about this possibility all the time. They are playing
havoc with my printer, and eating up the toner. It is especially
bad when I have to dump those strings out on a 110 baud ASR33
Teletype. Wears out the clutch and makes holes in the ribbon.

I challenge any c.l.c reader to provide any real working code that
uses a string of even SIZE_MAX / 2 length.

The item on hand is whether or not 'size==0' can ever be true. I claim
no.

Jeff
 
C

CBFalconer

Jeff said:
The item on hand is whether or not 'size==0' can ever be true.
I claim no.

If it is the result of a "size = strlen(s);" statement, of course
it can be zero.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
 
M

Michael Wojcik

Your premise here seems to be that I have never actually opened the
Standard, and am in fact guessing.

No, my premise is that you explicitly claimed that you had not
checked the Standard in this particular instance, and I can't see
any justification for your conclusion above.
If you happened to agree with me (or
Jordan), I wonder whether you'd have bothered to chastise me.

My argument appears to apply regardless of whether I agreed with you.
Instead,
you proceed believing (no pun intended) that your reading of the
Standard will justify the above paragraph, and the below statement.

I certainly do not believe that any reading of the Standard justifies
"the above paragraph", assuming the antecedent is my first paragraph
(and I don't see what else it could reasonably be). The Standard says
nothing about whether you should reply to a Usenet query, or whether
Jordan's question referred to the Standard, which are the only two
claims in the paragraph in question.
But, let's see what your reading of the standard yields:

Yes, that's the idea.
In other words, there _are_ circumstances where it actually _is_ legal,
even according to your reading of the Standard.

Since Jordan's question did not refer to those restricted circum-
stances, it applies to the general case; and in the general case,
his proposition ("this action is permitted by the Standard") is
false. "p -> q" does not imply "q".

Had Jordan asked, in some appropriate venue, "is it legal to stick a
knife into someone?", would you consider, "yes, if you're a surgeon
performing within the terms of your medical license and other
applicable regulation", and from that conclude that the answer to his
question is "yes"?

If so, I suggest you reconsider your personal definition of "legal",
as it does not appear to accord with common usage.
Why would it be
unlikely for a source file not to include certain standard headers?
I've seen quite a few.

Actually, this is more plausible than I originally thought. I
was thinking that the Standard allows standard headers to include
other standard headers, but it does not (there was a thread about
this on comp.std.c back in 2001[1]). The C++ standard does allow
this, which may have been what I was thinking of.

However, the point is moot; as I noted above, Jordan's question does
not specify any special circumstances, and neither does your initial
reply. As written they are false. (Well, technically yours isn't
necessarily false, since it's a claim of belief; but your belief, as
stated, does not accord with fact.)
So, your reading does not actually contradict Jordan's (or mine, for
that matter), at least not entirely.

I submit that it does - that as the question is expressed, there is no
partial correctness that can attach. It is incorrect as stated.
And sometimes, just sometimes, being a bit too self-righteous... ;-)

I don't believe I was self-righteous in the least. My claim about
the unlikelihood of the special circumstances was overly strong (due
to an erroneous unstated understanding which I ought to have verified
first), but aside from that I stand by everything I wrote. None of
it is intended to glorify me; I merely report what the Standard says,
and question - I think correctly - the utility of a response to a
question about the Standard which fails to refer to the Standard.
(That it did so ostentatiously might, by some, seem a bit self-
indulgent, but I will pass over that in silence.)


1. http://groups.google.com/group/comp.std.c/browse_thread/thread/d788da4142801822/f87020e3ea6fda78

--
Michael Wojcik (e-mail address removed)

Advertising Copy in a Second Language Dept.:
The precious ovum itself is proof of the oath sworn to those who set
eyes upon Mokona: Your wishes will be granted if you are able to invest
it with eternal radiance... -- Noriyuki Zinguzi
 
M

Michael Wojcik

Goring all who stand in their path with their sharp horns, such as
the above claim that zero is a possible value. See, I can quote it
too :)

Well, you know what they say: "Starve a troll, feed a sigmonster".
 
M

Michael Wojcik

Personally, when I wrote a strdup implementation (named ffstrdup) I
decided that anyone generating a string with length SIZE_MAX or longer
deserves to be shot, so I left it as undefined behaviour what the
library would do in such cases.

While I'll agree that excessively-long strings are not a hallmark of
good programming, I'll note that leaving such as undefined behavior
has produced a common and widely-exploited group of security holes,
most of which are exploited using integer-underflow attacks where
signed computations on data supplied by the attacker (eg a "request
length" field in a message received over a network) are coerced into
large unsigned values. (This is Sin 3 in Howard/LeBlanc/Viega's _19
Deadly Sins of Software Security_.)

Like many security holes, this relies on UB - but one of the
difficulties of secure coding is that the attacker can use UB, while
the defender must eschew it.

For that reason, in production code, I like to have my own object
size limits (configurable by the software administrator), rather than
simply trusting the implementation to decide when I've asked for too
much. I tend to side with CBF on this issue: the more sanity
checking, the better - and while UB is never my friend, it may be
someone else's.
 
M

Michael Wojcik

Redefining a keyword is only "legal" because they're only reserved
in translation phases 7 and 8 (C99 6.4.1#2). (This is a "shall"
requirement, so violating it causes UB, by 4#2.) Since macros are
expanded in translation phase 4, by the time phase 7 is reached,
macros that have the same names as keywords (eg "#define if foo")
no longer appear as identifiers in the translation unit.

I just realized there's an additional restriction on macro names
that are keywords - there cannot be any such before the inclusion
of a standard header (C99 7.1.2#4). That's irrelevant to the
original question, but I thought I should add it for completeness.
 
V

Vladimir S. Oka

Michael said:
No, my premise is that you explicitly claimed that you had not
checked the Standard in this particular instance, and I can't see
any justification for your conclusion above.

My wording was obviously unfortunate. I wanted to say: "I did not check
the Standard on this immediatelly before posting, I had before and this
is what I believe it said". FWIW, I'm not a native speaker.
My argument appears to apply regardless of whether I agreed with you.

Yes, of course it does. However, I believe the manner of your response
would have been different, provided you responded at all.
I certainly do not believe that any reading of the Standard justifies
"the above paragraph", assuming the antecedent is my first paragraph
(and I don't see what else it could reasonably be). The Standard says
nothing about whether you should reply to a Usenet query, or whether
Jordan's question referred to the Standard, which are the only two
claims in the paragraph in question.

You're right. Even I don't see now how I could have referred to the
"above paragraph". I apologise for any confusion, or worse.

<snipped quotes from the Standard and their discussion>

As I think I've said (if I didn't I wanted to), I do agree with your
reading of the Standard.
Since Jordan's question did not refer to those restricted circum-
stances, it applies to the general case; and in the general case,
his proposition ("this action is permitted by the Standard") is
false. "p -> q" does not imply "q".

Jordan said: "it is legal to do X".
You said: "no, what you just said is false".

To me, if "is legal" is false, "is not legal" is true, and that does
not allow exceptions, especially in pedantic mode you claim to be in.
As I see it "true" and "false" cannot be applied directly to what
Jordan said (and what I agreed with in original post).

If you told me: 'your reply to Jordan (and/or Jordan's original claim)
is not strictly correct (or not correct in all circumstances -- as is
the case), the only correct answer is "in many/most circumstances
you're not allowed to do it, but there are some where you can, and
here's why"', I'd have remained as quiet as a mouse.

Again, I /do/ agree with your analysis/interpreattion of the Standard.
What I /don't/ agree with is your trying to disqualify me using logic
that is broken, and your belief of what I mean and/or know.

I'll henceforth try to stay out of this sort of
pedantic-mode-standard-related discussions, as it became obvious to me
that I'm prone to misuse of my non-native English.

(BTW, In my graduate maths class we used `->` to express implication,
so I genuinely don't understand your: "p -> q" does not imply "q".)
Had Jordan asked, in some appropriate venue, "is it legal to stick a
knife into someone?", would you consider, "yes, if you're a surgeon
performing within the terms of your medical license and other
applicable regulation", and from that conclude that the answer to his
question is "yes"?

If so, I suggest you reconsider your personal definition of "legal",
as it does not appear to accord with common usage.

If my analysis above is correct, I'm now worried about yours. Yours
seems to want to lock up all the suregeons. ;-)
Why would it be
unlikely for a source file not to include certain standard headers?
I've seen quite a few.

Actually, this is more plausible than I originally thought. I
was thinking that the Standard allows standard headers to include
other standard headers, but it does not (there was a thread about
this on comp.std.c back in 2001[1]). The C++ standard does allow
this, which may have been what I was thinking of.

I was talking about (user) source files. Even Jordan did not say
anything about (standard) headers. Not being specific, I chose to
interpret the snippet he gave as sitting in a user source file (header
or not). As we've seen, that would be perfectly OK (legal? ;-) )
provided standard headers stdlib.h and string.h were not included.
However, the point is moot; as I noted above, Jordan's question does
not specify any special circumstances, and neither does your initial
reply. As written they are false. (Well, technically yours isn't
necessarily false, since it's a claim of belief; but your belief, as
stated, does not accord with fact.)

Your problem wiht my post seems to revolve around my (quite possibly
poor) choice of words. I wonder have I worded my post differently (yet
saying essentially the same thing) would your reply be so heated. This
is not meant as a defense, but as I already stated I am /not/ a native
English speaker.
I submit that it does - that as the question is expressed, there is no
partial correctness that can attach. It is incorrect as stated.

Here, I'll respectfully disagree.

I still firmly believe that the existence of (not at all contrived)
circumstances where it is legal, does not make that statement
"incorrect as stated" (to my ear, it was stated neither very precisely
nor in a very pedantic way).
I don't believe I was self-righteous in the least.

This was not writen to offend (note the smiley). If it did, I apologise
unreservedly.
My claim about
the unlikelihood of the special circumstances was overly strong (due
to an erroneous unstated understanding which I ought to have verified
first), but aside from that I stand by everything I wrote. None of
it is intended to glorify me; I merely report what the Standard says,
and question - I think correctly - the utility of a response to a
question about the Standard which fails to refer to the Standard.

My understanding of the question was that Jordan has read the Standard
himself and has drawn own conclusions (had a look above, and it /is/
what he said). I didn't think that quoting the Standard to him was what
he asked for, rather what conclusions other people have drawn from
their understanding of the Standard. In different circumstances, I'd
agree that quoting the Standard would have been sine qua non.

Let's drop this now. I agreed that you're correct in your
interpretation of the Standard (at least twice), and I don't intend to
hold grudge for anything that was said. I'll also try harder to spot
the pedantic-mode discussions and stay away from them. Hopefully, I'll
still be able to contribute something useful in other areas...

Cheers

Vladimir
 
F

Flash Gordon

CBFalconer said:
If it is the result of a "size = strlen(s);" statement, of course
it can be zero.

I happen to remember that the size in question was strlen(s)+1, but if
Jeff wants to claim this cannot be 0 he should address the points made
in this thread by myself and, IIRC, Jordan, on how a string with a
strlen of SIZE_MAX can legally be generated.
 
F

Flash Gordon

To clarify. Although the interface is not documented as to the
behaviour, it will do one of the following:
Fail on the memory allocation and abort the program, which is
accepted behaviour for this system.
Produce a resultant string shorter than the original string.

Seeing as there is no mechanism provided for the user to enter a long
string which will be executed, this means the worst you could achieve is
storing a truncated document.

Not documenting the behaviour means I can also put in checking for these
conditions and aborting the program if they happen (acceptable behaviour
for this system) without breaking any code that could be considered valid.
While I'll agree that excessively-long strings are not a hallmark of
good programming, I'll note that leaving such as undefined behavior

<snip>

I agree in the general case.
For that reason, in production code, I like to have my own object
size limits (configurable by the software administrator), rather than
simply trusting the implementation to decide when I've asked for too

We actually have limits else where in the system that will prevent
strings long enough to invoke undefined behaviour from occurring. These
limits being applied during the generation of the string.
much. I tend to side with CBF on this issue: the more sanity
checking, the better - and while UB is never my friend, it may be
someone else's.

Agreed. However if you can ensure that something cannot happen then
there is no need to check everywhere else that it hasn't happened.
 
A

aegis

Keith said:
aegis said:
Jordan Abel wrote: [...]
take SIZE_MAX 65535

char * foo = calloc(256,256);
memset(foo,"x",SIZE_MAX);

I'm pretty sure this is undefined behavior.

How so? The calloc() call can either succeed or fail; I don't see any
permission for it to do anything else. The memset() call is ok (if
calloc() succeeded). Note that it doesn't set the entire object; it
leaves the last byte as '\0'.
It parallels, I think, with an issue brought up
months ago(in comp.std.c) that labeled the
following as undefined behavior.

int array[10][10];

array[0][10] = 10;

and that each array object is not guaranteed to
be adjacent to the other.

As I understand the argument, the array elements are guaranteed to be
adjacent; the assignment invokes undefined behavior because an
implementation could do explicit bounds checking, not because the
address might be invalid. I don't see the connection between this and
the calloc() issue.

Douglas Gwyn presented a segmented memory model by where
the offsets from a particular base address of one of the arrays
would not exactly lead access to an adjacent array. By this reason
it was regarded as invoking undefined behavior. Because calloc
could be provide an object by the same means, it would imply
that the exploitation of accessing an adjacent array with a suitable
offset from the base address of its neighbor, would also invoke
undefined behavior. That is, the as-if rule can be applied here
for objects whose storage duration is allocated and not automatic
or static.
 
D

Dave Thompson

Jeff wrote:
Very poor code. Apart from the missing definition of clc_assert...
and CLC_RESTRICT strlen returns a size_t, which is unsigned. Thus
size can never be less than 1, and the "p = NULL" will never be
executed. Assuming CLC_RESTRICT has something to do with the
restrict qualifier, it is pointless because s is const. <snip>

'const' means the argument object can't be written through _this_
pointer. It doesn't prevent writing through other paths, and thus
doesn't allow (type-aliasable) caching. 'restrict' does.

- David.Thompson1 at worldnet.att.net
 
M

Michael Wojcik

Michael said:
Michael Wojcik wrote:
[legality of] #define strdup clc_strdup

OK, I think we're in agreement on the points relevant to C; I'll just
follow up to clarify some points. (And I'll note in passing that
while we may have disagreed in this thread, I generally find your
c.l.c posts appropriate and useful.)
My wording was obviously unfortunate. I wanted to say: "I did not check
the Standard on this immediatelly before posting, I had before and this
is what I believe it said". FWIW, I'm not a native speaker.

Fair enough. I took it too strongly, then.
Jordan said: "it is legal to do X".
You said: "no, what you just said is false".

To me, if "is legal" is false, "is not legal" is true, and that does
not allow exceptions, especially in pedantic mode you claim to be in.

OK. We have a difference of opinion here on what it means for
Jordan's proposition to be false.

I take Jordan's proposition to have an implicit universal qualifier:
"is X true independent of other qualifications?". It is not - X is
only true if additional conditions are satisfied. Thus the
proposition as a whole is false.

You seem to be interpreting it as having an implicit existential
qualifier: "is there at least one circumstance under which X is
true?". There is, thus the proposition is not, in your view, false.

So I'd agree with your statement "if 'is legal' is false, 'is not
legal' is true" - where we seem to have run into confusion is in
the meaning of "is not legal" in this case. I am claiming "is not
legal [in at least some circumstances]", and you are claiming "is
legal [in at least some circumstances]". Of course these two
statements are commensurate, provided there's at least one legal
circumstance and one illegal one (which there are).

Thus the disagreement arises from whether it is better to gloss
"is legal in some circumstances and illegal in others" as "is
legal" or "is not legal". And when put that way, most people
would probably say "neither", and spell the whole thing out.
If you told me: 'your reply to Jordan (and/or Jordan's original claim)
is not strictly correct (or not correct in all circumstances -- as is
the case), the only correct answer is "in many/most circumstances
you're not allowed to do it, but there are some where you can, and
here's why"', I'd have remained as quiet as a mouse.

OK, I think we've both arrived at that conclusion.
(BTW, In my graduate maths class we used `->` to express implication,
so I genuinely don't understand your: "p -> q" does not imply "q".)

I'm using "->" for implication too; I just spelled out the second
"imply" because I thought it would be clearer than

Exists(p,q) s.t. not ((p -> q) -> q)

In other words, "the fact that p implies q, does not suffice to imply
q [in the absence of asserting p]". (Of course this is just incom-
plete modus ponens.) Here it applies as "if certain circumstances
hold, then the definition is allowed; but without knowing whether
those circumstances hold, we cannot say the definition is allowed (in
the general case)".
Why would it be
unlikely for a source file not to include certain standard headers?
I've seen quite a few.

Actually, this is more plausible than I originally thought. I
was thinking that the Standard allows standard headers to include
other standard headers, but it does not (there was a thread about
this on comp.std.c back in 2001[1]). The C++ standard does allow
this, which may have been what I was thinking of.

I was talking about (user) source files.

Right. What I meant was that originally I was thinking that standard
headers could include other standard headers, which meant that
string.h or stdlib.h could be "silently" included in a source file
even if it was not explicitly included, nor included by a user header.

That would make it harder to safely employ the sort of definition
Jordan suggested, because if you included even one standard header,
you couldn't be sure that stdlib.h or string.h hadn't been also
included, thus reserving the identifiers in question.

However, as it turns out, the consensus on comp.std.c appears to be
that standard headers are not permitted to include other standard
headers, so this danger technically shouldn't exist. (In practice,
it appears that several implementations do include standard headers
in other standard headers. Oh well.)
Here, I'll respectfully disagree.

Fair enough; as I wrote above, I now believe this depends on the
interpretation of Jordan's "legal" (specifically, whether it implies
universality or existence).
 
V

Vladimir S. Oka

Michael said:
Michael said:
[legality of] #define strdup clc_strdup

OK, I think we're in agreement on the points relevant to C; I'll just
follow up to clarify some points. (And I'll note in passing that
while we may have disagreed in this thread, I generally find your
c.l.c posts appropriate and useful.)

(In a hushed voice: Thanks!)
Fair enough. I took it too strongly, then.

As written it could have easily been seen as flippant, I can see that
now. Wonderful thing, hindsight. ;-)

Jordan said: "it is legal to do X".
You said: "no, what you just said is false".

To me, if "is legal" is false, "is not legal" is true, and that does
not allow exceptions, especially in pedantic mode you claim to be in.

OK. We have a difference of opinion here on what it means for
Jordan's proposition to be false.

I take Jordan's proposition to have an implicit universal qualifier:
"is X true independent of other qualifications?". It is not - X is
only true if additional conditions are satisfied. Thus the
proposition as a whole is false.

You seem to be interpreting it as having an implicit existential
qualifier: "is there at least one circumstance under which X is
true?". There is, thus the proposition is not, in your view, false.

So I'd agree with your statement "if 'is legal' is false, 'is not
legal' is true" - where we seem to have run into confusion is in
the meaning of "is not legal" in this case. I am claiming "is not
legal [in at least some circumstances]", and you are claiming "is
legal [in at least some circumstances]". Of course these two
statements are commensurate, provided there's at least one legal
circumstance and one illegal one (which there are).

Thus the disagreement arises from whether it is better to gloss
"is legal in some circumstances and illegal in others" as "is
legal" or "is not legal". And when put that way, most people
would probably say "neither", and spell the whole thing out.

Yes, it seems so. I also believe Jordan's original proposition wasn't
very strictly put, allowing different takes on it.

I'm using "->" for implication too; I just spelled out the second
"imply" because I thought it would be clearer than

Exists(p,q) s.t. not ((p -> q) -> q)

Ah, I see now. I wasn't expecting "mixed" notation (I might have also
been thrown off by your double quotes positions). What you've written
is obviously correct.

<snip: spelling out the logic above>

Fair enough; as I wrote above, I now believe this depends on the
interpretation of Jordan's "legal" (specifically, whether it implies
universality or existence).

Now, if only Jordan came back and clarified his original question...

;-)

PS
It's refreshing seeing that around here one can still settle differences
in a civilised manner (trolls notwithstanding).

--
BR, Vladimir

With a gentleman I try to be a gentleman and a half, and with a fraud I
try to be a fraud and a half.
-- Otto von Bismark
 

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

Staff online

Members online

Forum statistics

Threads
474,175
Messages
2,570,942
Members
47,489
Latest member
BrigidaD91

Latest Threads

Top