• Greg (unregistered)

    My first guess is this comes from someone who was accustomed to write win32 code in which zeroing a struct with memset is more or less the standard way of doing this

  • (nodebb)

    Pendantry: the family of struct sockaddr_in must be AF_INET no matter which OS you're running on.

    Pendantry 2: If you're running Linux/390 (yes, Linux can be run on a zSystem, the spiritual inheritor of the 1960s System/360), '0'==0xF0 if your char type is unsigned...

  • (nodebb) in reply to Greg

    My first guess is this comes from someone who was accustomed to write win32 code in which zeroing a struct with memset is more or less the standard way of doing this

    It's pretty much standard (but not universal) everywhere to use memset, but it's usual to use 0 absolutely everywhere. '0' is ... unusual.

  • pudin9 (unregistered)

    @Steve The Cynic: Pedantry: "pendantry" is not a word.

  • Prime Mover (unregistered) in reply to pudin9

    Oh pudin9, you're such a pendant!

    (TRWTF is of course C)

  • I dunno LOL ¯\(°_o)/¯ (unregistered)

    Wow, I saw it right away, it was like a speed bump that hadn't been painted in years, so you didn't see it and drove over it at full speed. But then my thing is embedded, so little details like 0 vs '0' tend to be important. (And I still see no point in '\0' vs 0, it's like using "if (1=foo)" because 1993-era compilers can't catch = vs ==)

  • nani (unregistered)

    I'm guessing the author saw the pattern memset(&struct, '\0', sizeof(struct)) elsewhere. Then, in trying to imitate it, neglected the backslash that makes the value the null control character (0 in ASCII), rather than the character '0'.

    Another mystey is why some C programmers insist on using control character literals when integers would do just fine.

  • Sole Purpose Of Visit (unregistered) in reply to nani

    There are reasons. (You may regard them as insufficient, but still.)

    Consider trying to find all instances of a memset (as in this case) where the setting value is actually zero. Grep for memset and count. Grep for backslash zero and count. If the counts are the same, you're perfectly cromulent.

    Now try to do that without the backslash. It's far more prone to error.

    Equally, if I'm looking for eol characters, I would prefer them to be referenced as control characters, not as 13 or 10 or (in MS-speak) a combination of the two. You're going to find an awful lot of false positives in a million lines of code, otherwise.

    I'm not recommending this for anything other than C or C++, but if you're working at a sufficiently low level, you genuinely need whatever clarity you can get.

  • Vilx- (unregistered)

    I remember that in my youth when I was still dabbling in C/C++ (that was over 15 years ago) I also zeroed-out all the structs that I used. I don't remember doing it for this particular struct, and I was working predominantly on Windows, but still. The idea was that most of the time I just needed to set a few members of a struct and leave the rest as 0 anyway, so a memset + setting a few individual fields was the way of least typing. And future-proof too, if someone decided to change the struct down the road. But, yeah 0, not '0'. :)

  • (nodebb) in reply to I dunno LOL ¯\(°_o)/¯

    (And I still see no point in '\0' vs 0, it's like using "if (1=foo)" because 1993-era compilers can't catch = vs ==)

    For zero, I agree (outside of some stylistic consistency considerations), but for values greater than 0x7F, the difference between e.g. 0xA0 and '\xA0' can be of critical importance if you haven't added -f-unsigned-char or equivalent to the compiler command line.

  • Barry Margolin (github)

    I know they're equivalent, but I believe that using '\0' rather than 0 is appropriate when you're assigning or comparing a char.

    But this WTF does point out that it's easy to typo this as '0' and get the wrong result. That's what testing is for.

  • (nodebb) in reply to nani

    Another mystey is why some C programmers insist on using control character literals when integers would do just fine.

    For control characters (well, those in the 0-31 range for control characters in ASCII, anyway), it's sort of OK, except if you're comparing a variable known to be a character (type is char) to a number, which looks odd to my way of thinking.

    If the values are greater than 0x7F, the discrepancies noted above can bite you. If you haven't turned on the "char by default behaves as if it is unsigned" compile option(1), 0xA0 != '\xA0' because the character version is negative.

    (1) The standards leave this option's default state to the compiler-writer's discretion.

  • Carl Witthoft (google) in reply to pudin9
    "pendantry" is not a word.
    And yet, from wibble, I find "he coins the term ‘pendant’: Pendant (n): one who, by correcting others, gives himself (or herself) just enough rope by which to hang. "

    And dictionaryish claims this:
    pendantry is the unseasonable ostentation of learning. It may be discovered either in the choice of a subject or in the manner of treating it. Samuel Johnson

    Personally, I hearby define "pendantry" as the art of making pendants (jewelry). And there's already a Jewelry store in Melbourne called "The Pendantry."

  • (nodebb) in reply to nani

    Another mystey is why some C programmers insist on using control character literals when integers would do just fine.

    It has been my experience (with 2 different programmers) that they use literals so that there is no confusion when someone else reads the code because they think they're the only people in the Universe who know how the ASCII chart works.

  • (nodebb) in reply to Steve_The_Cynic

    If the values are greater than 0x7F, the discrepancies noted above can bite you. If you haven't turned on the "char by default behaves as if it is unsigned" compile option(1), 0xA0 != '\xA0' because the character version is negative.

    Does negative ^G make a sound?

  • Sole Purpose Of Visit (unregistered) in reply to Carl Witthoft

    Samuel Johnson (bless him) was well-known for making extremely verbose jokes in his dictionary, and also for a smidgeon here or there of failing to cross-check.

    In this case he very definitely meant "pedantry." And I would further argue that he meant "unreasonable," not "unseasonable," because the latter means nothing at all in context and the former can be understood by any seasonable English speaker.

    Keep swinging that pendant!

  • Worf (unregistered)

    Of course, the real problem is the socket functions - all requiring you to use "bad" programming practices as standard. Like casting. One shouldn't need to cast except in exceptional circumstances. Unless you're using sockets, in which case, casts are perfectly normal and required in order to actually do anything.

    Anyhow, Windows is usually something like SOMETHING something; memset(&something, 0, sizeof(something)); // ZeroMemory() is a "native" Windows API for this too something.szLen = sizeof(something);

    To version structures and have binary compatibility, WIndows has a size attribute you must set on structs so when they get extended, the code can handle it. Except of course, then you have to deal with SOMETHINGEX, SOMETHINGEX2, ...because that's the way they went instead of going with longer structs.

  • (nodebb) in reply to pudin9

    "pendantry" is not a word

    Forum memes sometimes leak. It most certainly is a word in the context in which it was coined (as a joke).

  • Fworg64 (unregistered) in reply to Bananafish

    Does negative ^G make a sound?

    All real chimes consist of positive and negative ASCII codes; however, they are symmetric, so the negative half is usually ignored

  • tbo (unregistered) in reply to dkf

    What forum?

  • Chris (unregistered)

    I think if you're comparing characters to particular control characters, your code will be actually be saying what it is doing if you use e.g. '\n', rather than whatever number it is. Otherwise the readability of your code is down to how much the next person to look at it works directly with ASCII all the time. E.g. I'm familiar with ASCII, but can't tell you off the top of my head what any of the control characters map to, because I don't actually use them all that often.

    If you're zeroing out memory, using 0 instead of '\0' is clearer. It just so happens that '\0' maps to 0, but that's not what your code is doing. You aren't filling the memory with the null character, you are filling it with zeroes.

  • löchleindeluxe (unregistered)

    Sooo… reading the comments, my takeaway is that C##23 needs a way for a datatype to override what memset does to it, a la operator overloading, so in this case, it could set it all to zero apart from the field that needs to be AF_INET?

    :-)

  • Have you tried turning it off, and then on again? (unregistered)

    "Without context, I suspect this was programming by incantation: someone learned the hard way that variables in C don't start with a known value, "

    Objects with automatic storage duration and no initializer have inderterminate values. Anythign with static storage duration and no initializer is 0-initialized.

    See: https://en.cppreference.com/w/c/language/initialization (implicit initialization)

  • Chris (unregistered)

    The horrid thing is MSVC auto-fills things with 0's if in Release mode, but something else when in Debug.

  • jochem (unregistered) in reply to nani

    I would guess that's because '\0' is a char, while 0 is an int. But I'm only guessing. And there would be better ways on ensuring a char.

  • john (unregistered)
    Comment held for moderation.
  • Navnitrai (unregistered)
    Comment held for moderation.
  • (nodebb) in reply to tbo

    What forum?

    Yes, the what forum; what.thedailywtf.com

  • Navneet (unregistered)
    Comment held for moderation.
  • Schoolzpro (unregistered)
    Comment held for moderation.
  • Beauty stoke (unregistered)
    Comment held for moderation.
  • CmdrKien (unregistered) in reply to Chris

    Filling uninitialized values to something other than 0 is supposed to help find errors, as a lot of the time, it's the 0 fill that masks the uninitialization.

  • (nodebb) in reply to nani

    why some C programmers insist on using control character literals when integers would do just fine.

    It's because 0 is an integer: a numeric type of machine-defined size, usually 2 or 4 bytes. '\0' is a byte.

    In early C, the char data type was strictly defined to be a byte. Void pointers didn't exist; char pointers were used instead (i.e., pointers to a sequence of bytes).

    "Char == byte" is maintained for backwards compatibility these days, but that equivalence is firmly ingrained in the minds of some old-school developers, too. To them, it just makes more sense to fill a byte range with a byte value rather than an integral value.

Leave a comment on “Mark it Zero”

Log In or post as a guest

Replying to comment #532220:

« Return to Article