Implementing strstr

S

spinoza1111

You're arguing with someone who is not a first-year CS student and
claims to have needed TWO HOURS to implement strstr.
Is there any genuine point in pointing out errors?

A quick and nasty strstr should only take a minute or so to write.

/*
   quick and nasty strstr. Untested. Posted to comp.lang.c "as is"
without warrantry or guarantee of any kind, including implied
warrantry of merchanability or fitness for any particular purpose.
*/
char *mystrstr(char *str, char *sub)
{
  size_t i; /* If you think this is ugly, join the campaign for 64-bit
ints */
  while(*str)
  {
    for(i=0;str==sub && str;i++);
    if(!sub)
       return str;
    str++;
  }
  return 0;

}

However it's a bit cryptic, particularly the for loop.
Whilst there's always the argument that as long as the interfaces are
nice, the code doesn't matter, I'd like to see a rather better job.
Then it  will return a match to the first character if sub is the
empty string. I don't know offhand whether this is allowed. I'd have
to check the standard for a real implementation intended to be shipped
to someone else.
Two hours isn't unreasonable for a production-quality strstr.


About ten minutes of work produces rel 1.12. This fixes the bug that
Ben noted, where a = was used in place of ==. Another bug was found
such that we noted the char "handle" starting, not one after the start
of the string being tested for a match, but at the start of that
string.

The code once again executes the test suite, but:

* Far more tests are needed.

* A correctness proof in English is clearly needed. Dijkstra would
have done this first.

#include <stdlib.h>
#include <stdio.h>

// ***************************************************************
// * *
// * strstr *
// * *
// * This function (strstr) finds a string, probably as fast as *
// * possible without extra memory usage over and above brute *
// * force. *
// * *
// * In searching a Nul terminated string for a substring, there *
// * are logically three possibilities in a left to right *
// * traversal of the master string that (1) looks for the *
// * first character of the target and then (2) matches all the *
// * remaining characters:
// * *
// * * (Erroneous): on the failure of a partial match, *
// * restart at the first nonmatching character. This is *
// * fast but wrong, since the matching string may *
// * overlap the partial match. *
// * *
// * * (Too slow): on the failure of a partial match, start*
// * one past the first character (of the partial match) *
// * *
// * * (Just right): while matching characters, note the *
// * leftmost character in the searched string, to the *
// * right of the first matched character, that matches *
// * both that character and, of course, the first *
// * character of the target. *
// * *
// * C H A N G E R E C O R D --------------------------------- *
// * DATE PROGRAMMER DESCRIPTION OF CHANGE *
// * -------- ---------- --------------------------------- *
// * 03 18 10 Nilges Version 1.0 *
// * *
// * 03 19 10 Nilges Version 1.1 *
// * *
// * 1. Incorporates Pete's suggestion*
// * that a null target string is *
// * always found at the start of *
// * the master string. *
// * *
// * 2. Results display enhanced *
// * *
// * 03 19 10 Nilges Version 1.11: bug: ptrMaster was *
// * incorrectly set one past the *
// * ptrHandle *
// * *
// * 03 20 10 Nilges Version 1.12 *
// * *
// * 1. Bug (reported by BB): *
// * assignment used in place of *
// * equality test *
// * *
// * 2. Bug: incorrect test for noting *
// * char handle goes all the way *
// * back to start of string *
// * *
// * *
// * ----------------------------------------------------------- *
// * *
// * To find a string, oh Muse! I sing, inside another String! *
// * Alternatives to me come in Three, ah, that's the thing: *
// * For the one thing for which the Wise must watch is mayhap, *
// * Partial occurences that most melancholy, overlap. *
// * The first is base, mechanical, low, and tragicomical: *
// * It's to restart from the previous beginning plus but One *
// * Oh what Mayhem to true Programming is thereby, done! *
// * But the job it will do, as did Hercules, *
// * His Labors for the Goddess cruel in Seneca's tragedies: *
// * Arduously and ignobly like unto the meanest Hind *
// * That knoweth not his Elbow from his Behind. *
// * The second is worse, a boner, a solecism, and a Seebach: *
// * The second restarts at the character that doth match! *
// * Oh muse! Such hellish Sights before me yawn: *
// * But be assur'd, 'tis darkest just before the Dawn. *
// * Shout for Victory, oh Thrace, and smite the Harp, and Grin: *
// * For lo, we start at the leftmost "handle" of the string *
// * When it occureth in *
// * The tragic partial match that hath failed us. *
// * If no such handle exists, then we can restart *
// * At the point of match failure: no, 'tis not a brain fart. *
// * Now we spy our magic bus: *
// * For this is the best Al Gore ithm *
// * That we can hope for in C, a language without Rhyme, or *
// * for that matter, Oh Muse! rhythm. *
// * *
// ***************************************************************

#define TRUTH -1
#define FALSITY 0
#define NULLITY 0

char * strstrWithIndex(char *strMaster,
char *strTarget,
int *ptrIndex)
{
char *ptrMaster = NULLITY;
char *ptrTarget = NULLITY;
char *ptrHandle = NULLITY;
char *ptrMasterStart = NULLITY;
int booFound = FALSITY;
*ptrIndex = 0; // Rel. 1.1
if (!*strTarget) return strMaster; // Rel. 1.1
if (!*strMaster) return 0; // Rel. 1.1
for (ptrMaster = strMaster; *ptrMaster;)
{
for (;
*ptrMaster && *ptrMaster != *strTarget;
ptrMaster++);
ptrTarget = strTarget;
*ptrIndex = ptrMaster - strMaster;
ptrHandle = 0;
ptrMasterStart = ptrMaster; // Rel 1.12
for (;
*ptrTarget
?
(*ptrMaster
?
(*ptrMaster==*ptrTarget ? TRUTH : FALSITY)
:
FALSITY)
:
(booFound = TRUTH, FALSITY);
ptrMaster++, ptrTarget++)
{
if (ptrHandle == 0 // Rel 1.12
&&
ptrMaster > ptrMasterStart
&&
*ptrMaster == *strTarget)
ptrHandle = ptrTarget;
}
if (booFound) return strMaster + *ptrIndex;
if (ptrHandle) ptrMaster = ptrHandle; // Rel. 1.11 bug fix
}
*ptrIndex = 0;
return 0;
}

char * strstr(char *strMaster, char *strTarget)
{
int ptrIndex = 0;
return strstrWithIndex(strMaster, strTarget, &ptrIndex);
}

int main(void)
{
char *ptrIndex1 = NULLITY;
int intIndex1 = 0;
printf("strstr Version 1.12\n\n");
printf("Expect 0: %x\n", *strstr("", ""));
printf("Expect '0': '%c'\n", *strstr("0123456789", ""));
printf("Expect 0: %d\n", strstr("", "0"));
printf("Expect 0: %d\n", strstr("Here", "There"));
ptrIndex1 = strstrWithIndex("There", "here", &intIndex1);
printf("Expect 1: %d\n", intIndex1);
ptrIndex1 = strstrWithIndex("They seek him here",
"here",
&intIndex1);
printf("Expect 14: %d\n", intIndex1);
ptrIndex1 = strstrWithIndex("They seek him there",
"here",
&intIndex1);
printf("Expect 15: %d\n", intIndex1);
ptrIndex1 = strstrWithIndex
("The clc regs seek him everywhere",
"here",
&intIndex1);
printf("Expect 28: %d\n", intIndex1);
printf("Expect 'h': '%c'\n", *ptrIndex1);
ptrIndex1 = strstrWithIndex
("Is he in Heaven? Or in Hell?",
"?",
&intIndex1);
printf("Expect 15: %d\n", intIndex1);
printf("Expect '?': '%c'\n", *ptrIndex1);
ptrIndex1 = strstrWithIndex
("That damn'd elusive Spinoza won't tell!",
"Spinoza",
&intIndex1);
printf("Expect 20: %d\n", intIndex1);
printf("Expect 'p': '%c'\n", *(ptrIndex1+1));
printf("Expect '0': '%c'\n", *strstr("0123456789", "0"));
printf("Expect '1': '%c'\n", *strstr("0123456789", "1"));
printf("Expect '0': '%c'\n", *strstr("0123456789", "0"));
printf("Expect '9': '%c'\n", *strstr("0123456789", "9"));
printf("Expect '5': '%c'\n",
*strstr("0123456789", "345") + 2);
printf("Expect '8': '%c'\n", *strstr("0123456789", "89"));
ptrIndex1 = strstrWithIndex("0123456789A89AB",
"89AB",
&intIndex1);
printf("Expect 11: %d\n", intIndex1);
return 0;
}
 
S

Seebs

A quick and nasty strstr should only take a minute or so to write.
Right.

However it's a bit cryptic, particularly the for loop.
Whilst there's always the argument that as long as the interfaces are
nice, the code doesn't matter, I'd like to see a rather better job.
Then it will return a match to the first character if sub is the
empty string. I don't know offhand whether this is allowed. I'd have
to check the standard for a real implementation intended to be shipped
to someone else.
Two hours isn't unreasonable for a production-quality strstr.

I'm not sure about that. It's a pretty simple function. And yes, yours
is fine -- the first occurrence of an empty string is the zero bytes
before the first character of the haystack.

But, that said... It's not as though Nilges produced one of production
quality. He spent two hours producing something that wouldn't get a
passing grade in a first-semester programming course. That's why I
have concluded that it's simply not worth trying to explain his bugs
to him.

-s
 
S

spinoza1111

A quick and nasty strstr should only take a minute or so to write.

I hate those words, "quick and dirty", or "quick and nasty", whether
they're from Seebs or you, Malcolm. But I understand that in your
case, but not Seebs, that you distance yourself from them, since like
me you don't have to be a programmer, subordinate in the programming
dreamtime to enslaving myths.

What they mean is that programmers, rather in the way that symphony
orchestra members who don't get adequate rehearsal time, are never
given, in capitalist second nature, enough time as a matter of course.
And, this is for the same reason that no real, ordinary programmers
have anything like economic security by virtue of being programmers,
only if they live in France, or some such country which gives dignity
and self-respect to all in the form of a safety net and worker
ownership.

As a minatory phrase, "quick and dirty" means that the programmer is
regarded, without any chance for appeal or review, as one of Frederick
Taylor's "typical", average and therefore definitional worker, who
will, if given enough time, use most of that time to loaf on the job.
It makes invisible the countless actual programmers who would, like
most other human beings, be delighted to do a good to great job if
given a decent amount of time in a humane (four day) work week.

The final irony is that Seebach, who barges in here to call me names
and condemn me for taking "too long" while pretending in a cowardly
fashion to speak to others, takes megatime to deliver anything useful
and in all cases in terms of my standards of literate programming,
delivers a mess. Over in another thread, he presents a pseudo root
simulator for Linux that, he says, took two months and yet has code
that tests indexes for usability after using them.

These bugs are, I believe, different in kind from the normal
programmer bug, for reasons I have outline elsewhere, because while a
C programmer might mistakenly type "=" meaning "==", it takes real
work to put the index test after the &&. It also takes what I feel to
be an insensitivity to the elegance of lazy evaluation. The
distinction between = & == in C has long been recognized as a "bug" in
the sense of a language design boner.

I believe Seebach does so because he's exclusively a creature of the
reified and second-hand world of corporate programming, not having any
academic preparation in freedom of thought and collegiality and indeed
contemptuous of any notion that any such things exist. In this
twittering world, a constructed Concept (the "bug") is uninterrogated
to show differences in bugs other than convenient taxonomies, and the
Concept becomes naturally more important than human lives (in the case
of collateral damage in military software where the de minimis
connotation of "bug" dates from hasty and high pressure WWII projects)
and reputation (in the case of Schildt).
/*
   quick and nasty strstr. Untested. Posted to comp.lang.c "as is"
without warrantry or guarantee of any kind, including implied
warrantry of merchanability or fitness for any particular purpose.
*/
char *mystrstr(char *str, char *sub)
{
  size_t i; /* If you think this is ugly, join the campaign for 64-bit
ints */
  while(*str)
  {
    for(i=0;str==sub && str;i++);
    if(!sub)
       return str;
    str++;
  }
  return 0;

}

However it's a bit cryptic, particularly the for loop.
Whilst there's always the argument that as long as the interfaces are
nice, the code doesn't matter, I'd like to see a rather better job.
Then it  will return a match to the first character if sub is the
empty string. I don't know offhand whether this is allowed. I'd have
to check the standard for a real implementation intended to be shipped
to someone else.
Two hours isn't unreasonable for a production-quality strstr.
 
N

Nick

Dr Malcolm McLean said:
A quick and nasty strstr should only take a minute or so to write.

I've seen it implemented using strchr and strcmp - something like this:

/* written straight into newsreader - utterly untested */
a_strstr(const char *substrate, const char *pattern) {
while(substrate = strchr(substrate,*pattern) {
if(strcmp(substrate,pattern) == 0)
return substrate;
}
return NULL;
}

You can make it fractionally more efficient by advancing the pointers by
one before comparing but you need to be careful then with short
substrates.
 
D

Dr Malcolm McLean

I've seen it implemented using strchr and strcmp - something like this:

/* written straight into newsreader - utterly untested */
a_strstr(const char *substrate, const char *pattern) {
  while(substrate = strchr(substrate,*pattern) {
    if(strcmp(substrate,pattern) == 0)
      return substrate;
  }
  return NULL;

}

You can make it fractionally more efficient by advancing the pointers by
one before comparing but you need to be careful then with short
substrates.
This one won't work, strcmp("Fred is dead", "Fred") returns non-zero.
You need strncmp, which entails a call to strlen() to get the length
of the pattern.
 
N

Nick

Dr Malcolm McLean said:
This one won't work, strcmp("Fred is dead", "Fred") returns non-zero.
You need strncmp, which entails a call to strlen() to get the length
of the pattern.

Good point. I said I'd not tested it. That's exactly what the BSD code
you can find on the web (written by Chris Torek, no less) does -
although it walks the string explicitly char by char.
 
S

spinoza1111

I'm not sure about that.  It's a pretty simple function.  And yes, yours
is fine -- the first occurrence of an empty string is the zero bytes
before the first character of the haystack.

But, that said... It's not as though Nilges produced one of production
quality.  He spent two hours producing something that wouldn't get a
passing grade in a first-semester programming course.  That's why I

I'll ask you again, and I will keep asking you, if necessary in a
courtroom.

How would you know?

By your own admission, you have never taken a single class in
computer science. Because you're a pretentious autistic twit, you
interfered with homework assignments as a tutor, and we have no
information as to whether your "assistance", based as it was with
playing with the toys in your bedroom, was of any value.

If your academic family homeschooled you, this is merely a reason for
outlawing homeschooling altogether. I have long suspected that it will
create a generation of creeps who shit on people, because they haven't
learned how to work in groups.

You scorn the simplicity of strstr (having proven yourself incompetent
at the simplest of problems: strlen). Having taught computer science
and read Dijkstra, I am aware that simple problems are the best for
exposition and contain depths. Malcolm has made some interesting
comments in this regard. I'm not interested in hiding my incompetence
(as you seem to be) by pretending you're writing OS code ("pseudo" is
apposite in your case).

Peter, you took two months to write a pseudo root simulator of
questionable utility in which you test an index for validity after you
use it, and use the letter o as a variable name.

So **** off. Businessmen like to reference academia because it's
something they think they can buy and sell. It's not. You're not even
a businessman, nor even anything resembling a man. You're a nasty
little clerk and an incompetent programmer who's here, apparently on
behalf of your employer, to get incompetent code debugged by slaves.
have concluded that it's simply not worth trying to explain his bugs
to him.

No, but I had to explain order-of-magnitude more egregious bugs (off
by one strlen) to you, and Kiki. You claim elsewhere that you get the
simple things wrong but are good at the complex things because Mommy's
little darling gots ADHD (an unprofessional revelation which damages
your employer), but what's interesting is the Popperian
unfalsifiability of this claim.

Sure, Einstein (cf Kaufmann 2007) was bad at math in fact. However,
Einstein NEVER attacked his colleauges as you attack Schildt (that was
Edward Teller, the genocide who invented the hydrogen bomb, and your
attacks suggest a deep insecurity based on a lack of real technical
accomplishment. I've searched for accomplishments comparable to what I
did when I was your age, and have found nothing. According to
Kaufmann, Einstein compensated for his mathematical deficiencies
(where in fact he was merely not a mathematician like Godel) by being
an excellent visual and physical reasoner. But your lack of talent in
the small doesn't scale. It don't turn into fine wine, Peter. And you
give me little reason to give you "the benefit of the doubt".
 
S

spinoza1111

This one won't work, strcmp("Fred is dead", "Fred") returns non-zero.
You need strncmp, which entails a call to strlen() to get the length
of the pattern.

Good point. It's why I write complete and literate documentation
before coding. We need to think ahead. I missed that bug in Fred's
code.

The only reason I didn't use pre-existing str functions is I refuse to
use string.h.
 
S

spinoza1111

Good point.  I said I'd not tested it.  That's exactly what the BSD code
you can find on the web (written by Chris Torek, no less) does -
although it walks the string explicitly char by char.

Gee, no Heathfield Factor. Wonder where the big lug is.
 
S

spinoza1111

spinoza1111wrote:

You can write all of these portably in C,
using only <stddef.h> for size_t

void *memset(void *s, int c, size_t n);
void *memcpy(void *s1, const void *s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
void *memchr(const void *s, int c, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
size_t strlen(const char *s);
char *strcpy(char *s1, const char *s2);
char *strncpy(char *s1, const char *s2, size_t n);
char *strcat(char *s1, const char *s2);
char *strncat(char *s1, const char *s2, size_t n);
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
size_t strspn(const char *s1, const char *s2);
size_t strcspn(const char *s1, const char *s2);
char *strpbrk(const char *s1, const char *s2);
char *strstr(const char *s1, const char *s2);
char *strtok(char *s1, const char *s2);

Yes, you can. But even your rewrite will preserve Nul termination,
which I claim sucks.
 
B

Ben Bacarisse

spinoza1111 said:
About ten minutes of work produces rel 1.12. This fixes the bug that
Ben noted, where a = was used in place of ==.

I did not claim that = in place of == was a bug. In fact it is
obvious that putting == back introduces more bugs. My point was that
you did not know what your code was doing: you reported favourably on
a bug fix that could not possibly have any effect. You can't fix (or
do pretty much anything with) code you don't understand.

I don't expect you to change your style -- you've evolved it to
provoke a response here rather than make your code clear -- but if
there are any people learning C who are tempted to copy it: please
don't -- it confuses even the author of it.

<snip>
 
S

Seebs

I like to discuss C.
Sometimes I make mistakes and then other people correct me.
Sometimes, when I don't make a mistake,
other people will attempt to correct me.

You have a point. I fell into the trap of assuming that a post in
reply to something written by Nilges was offered in the hopes that he'd
comprehend it.

-s
 
S

Seebs

You can write all of these portably in C,
using only <stddef.h> for size_t

You can.

However, the statement by Nilges above highlights a particular kind of
madness.

Why doesn't he use string.h? From the rest of what he's written, I'd guess
that it's because he thinks null-terminated strings are error-prone and
poorly designed.

So. Avoiding null-terminated strings? A plausible solution.

Writing your own code to manipulate them, demonstrating repeatedly that,
at least for you, the design is indeed highly error-prone, and simply beyond
your abilities to debug in a reasonable amount of time? Stupid.

If you have to use null-terminated strings, the sane thing to do would
be to use the *already debugged* standard tools, reducing your exposure
to the sorts of errors that crop up when you start messing with strings
directly.

-s
 
S

Seebs

I only write like that as a programming exercise.
Yup.

There is no end of places in C programming to make mistakes in.
In my opinion, the main usefulness of this newsgroup,
is to learn how to write so as to avoid making mistakes in C.

That can be a very good idea.
After a while, I don't think that you will continue to wonder
about why Nilges does what he does.

I probably will until either I can confirm the specific insanity or
come up with a rational explanation. Nilges does not write like someone
who thinks he is trying to learn to avoid mistakes; he writes like
someone who is trying to prove that everyone else is wrong about how
to do things.

-s
 
M

Morris Keesan

#define TRUTH -1
#define FALSITY 0
#define NULLITY 0

What's the point of defining TRUTH as -1, instead of accepting the
language-defined truth value of 1, especially since the only thing
you ever do with this value (based on an admittedly quick scan of your
code) is assign it, under some conditions, to booFound, whose value
is then tested by "if (booFound)"?
Likewise, why obfuscate things by defining your own NULLITY macro
instead of using the standard-defined NULL?

....
(*ptrMaster==*ptrTarget ? TRUTH : FALSITY)
If TRUTH were defined in the expected way, this would be equivalent to
(*ptrMaster == *ptrTarget)
which would be much clearer to the reader. The larger expression,
*ptrTarget
?
(*ptrMaster
?
(*ptrMaster==*ptrTarget ? TRUTH : FALSITY)
:
FALSITY)

appears to have been composed solely for its confusion factor, since as
a boolean expression it's equivalent to
(*ptrTarget && *ptrMaster && (*ptrMaster == *ptrTarget))
or the even simpler
(*ptrTarget && (*ptrTarget == *ptrMaster))
 
D

Dr Malcolm McLean

What's the point of defining TRUTH as -1, instead of accepting the
language-defined truth value of 1,
~TRUTH == FALSITY;
also, if booleans are one bit, a set bit is -1 in two's complement
notation.
As an added bonus you get an error if you try to get the root of
TRUTH, unless you accept that the answer is complex.
 
S

Seebs

What's the point of defining TRUTH as -1, instead of accepting the
language-defined truth value of 1, especially since the only thing
you ever do with this value (based on an admittedly quick scan of your
code) is assign it, under some conditions, to booFound, whose value
is then tested by "if (booFound)"?

He's an idiot.

Specifically, he's picked it because, on some machines, it's all-bits-one,
thus "less like zero". However, this is overwhelmed by the much stronger
arguments in favor of 1:
* It's what boolean operators generate for truth.
* It's not a negative value -- which values are often used
to indicate failure, by contrast to meaningful yes/no values.
Likewise, why obfuscate things by defining your own NULLITY macro
instead of using the standard-defined NULL?

He's an idiot.

So far as we can tell, he's become convinced of two things:

1. He's really good at programming, and will show us all how C should be
used.
2. Everything C does is wrong.

Therefore, he goes out of his way to avoid using C in a way consistent with
the language's design. Which is interesting, because even if a language's
design is utter pants, carefully violating that design is one of the few
things you can do that genuinely makes things worse.
...
If TRUTH were defined in the expected way, this would be equivalent to
(*ptrMaster == *ptrTarget)
which would be much clearer to the reader.

Do you honestly think that someone who named variables "ptrIndex0" through
"ptrIndex3" is concerned with "clear to the reader"?

For that matter, note that he's missed the point anyway; he's already
relying on the standard boolean behavior. What he should do, of course,
is:

int truth_values_internal = { TRUTH, FALSITY, TRUTH };
int *truth_of = truth_values_internal[1];

Thus,
truth_of[TRUTH] == TRUTH
truth_of[FALSITY] == FALSITY
truth_of[1 == 1] == TRUTH
appears to have been composed solely for its confusion factor, since as
a boolean expression it's equivalent to
(*ptrTarget && *ptrMaster && (*ptrMaster == *ptrTarget))
or the even simpler
(*ptrTarget && (*ptrTarget == *ptrMaster))

Oh, come on. It's not confusion factor. It's that when you first learn
about the ternary operator, it's SO COOL. Also, remember, he doesn't want
to rely on the standard boolean operators, because by definition, since
they're part of C, their designs are of course completely wrong. So he
doesn't rely on &&, because if you use &&, that's a pointless premature
optimization because the short-circuiting rule is a stupid optimization that
shows that the language designers were incompetent and the standard has been
driven by autistic twerps.

Read his psychotic-break rants about the meaning of the word "clear" sometime
before you suggest that he would try to write for clarity. In short, I don't
think it's on the table.

.... I should point out, it's not that I in any way disagree with your
criticisms. It's just that, by phrasing them as though you expect him to
have a response which is even recognizably lucid, let alone coherent,
you're giving the impression that you're speaking to the wrong audience.
Write for the rest of the readers.

-s
 
B

Ben Bacarisse

Dr Malcolm McLean said:
~TRUTH == FALSITY;

!FALSITY != TRUTH and !!TRUTH != TRUTH. There is no reason to favour
the action of ~ over that of !. In fact there are good reasons *not*
to favour it. For example, your claim (~TRUTH == FALSITY) is not the
case in two out of the three valid number representations that C
permits.
also, if booleans are one bit, a set bit is -1 in two's complement
notation.

There is no reason to assume that one bit Booleans are signed rather than
unsigned. "If they are 1 bit, a set bit is 1 in binary" is just a
valid a supporting statement.
As an added bonus you get an error if you try to get the root of
TRUTH, unless you accept that the answer is complex.

And you find that TRUTH is less the FALSITY when it should be so much
more.

Any number of cute facts can be used to try to support one or other
side but the non-cute, boring fact that C's logical operators produce
0 and 1 trumps them all. Doing anything else is likely to come over
as an affectation at best and at worst will lead to confusion.
 
I

Ike Naar

For that matter, note that he's missed the point anyway; he's already
relying on the standard boolean behavior. What he should do, of course,
is:

int truth_values_internal = { TRUTH, FALSITY, TRUTH };
int *truth_of = truth_values_internal[1];

That is not valid C; do you mean:

int truth_values_internal[] = { TRUTH, FALSITY, TRUTH };
int *truth_of = &truth_values_internal[1];
 
S

Seebs

For that matter, note that he's missed the point anyway; he's already
relying on the standard boolean behavior. What he should do, of course,
is:
int truth_values_internal = { TRUTH, FALSITY, TRUTH };
int *truth_of = truth_values_internal[1];
That is not valid C; do you mean:
int truth_values_internal[] = { TRUTH, FALSITY, TRUTH };
int *truth_of = &truth_values_internal[1];

Uh, yeah. That.

Actually, I think I meant "truth_values_internal + 1", but in any event,
you get what I mean.

In my defense, I may have spent a *tiny* bit less than two full hours thinking
about that.

-s
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top