Slashdot Mirror


Null References, the Billion Dollar Mistake

jonr writes "'I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. In recent years, a number of program analysers like PREfix and PREfast in Microsoft have been used to check references, and give warnings if there is a risk they may be non-null. More recent programming languages like Spec# have introduced declarations for non-null references. This is the solution, which I rejected in 1965.' This is an abstract from Tony Hoare Presentation on QCon. I'm raised on C-style programming languages, and have always used null pointers/references, but I am having trouble of grokking null-reference free language. Is there a good reading out there that explains this?"

612 comments

  1. null or not null, that is the question by alain94040 · · Score: 5, Interesting

    It's hard to imagine life without the null pointer! That being said, the author is not really responsible for billions of dollars of mistakes, the programmers are.

    If there is one thing I'll complain about, it's the choice of the value 0. It's almost impossible to trace it. When we do hardware debug of chips, we prefer to use a much more visible value such as 0xdeadbeef for instance. Otherwise a bad pointer will bland too much with all the uninitialized values out there.

    In assembly, null has no particular meaning. If you dereference an address, you can do it in any range you like. It's just that 0 on most machines was not a good place to store anything, since it would typically be used to boot the OS or some other critical IO function that you don't want to mess up with. Thus null was born.

    1. Re:null or not null, that is the question by CTalkobt · · Score: 4, Insightful

      When debugging at the hardware level it's fairly common to fill uninitialized memory (or newly allocated in a debug version of the malloc libraries) with a value that will either cause the computer to execute a system level break ( eg: TRAP / BRK etc) or something fairly obvious such as ($BA).

      If you don't like the 0's, then replace your memory allocation library.

      --
      There's a gorilla from Manilla whose a fella that stinks of vanilla and has salmonella.
    2. Re:null or not null, that is the question by gr8_phk · · Score: 1

      I'd like it if there was a "prefetch" instruction to fill cache, but that ignored references to address zero. This way you could prefetch all pointers unconditionally to increase performance. Compilers could then insert these prefetches automatically.

    3. Re:null or not null, that is the question by LiquidCoooled · · Score: 2, Informative

      its not the memory allocation library that is at fault.
      its the expectation of the app developer to instincively do

      if(!ptr){ ... }

      you have to change the fundimental way the compiler works and alter boolean logic to account for existing code which works like this to then accept 0xdeadbeef under some conditions and not others.

      --
      liqbase :: faster than paper
    4. Re:null or not null, that is the question by jeremyp · · Score: 3, Insightful

      That's all very well, but in a production environment when dereferencing a NULL pointer you'd probably rather have the program crash than carry on merrily with bad data. With a zero null value, you can easily arrange for this to happen by protecting the bottom page of memory from reads and writes. That way, even an assembly language program can't dereference a null pointer.

      --
      All I want is a secure system where it's easy to do anything I want. Is that too much to ask ~~ Randall Munroe
    5. Re:null or not null, that is the question by larry+bagina · · Score: 2, Informative

      In assembly, 0 is much easier to check for.

      --
      Do you even lift?

      These aren't the 'roids you're looking for.

    6. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      It's hard to imagine life without the null pointer! That being said, the author is not really responsible for billions of dollars of mistakes, the programmers are.

      While it's correct, things should be designed around stupidity.

      If the software running my car were to fail at a critical moment, it would matter little to me whether the mistake was due to programmer error or not.

    7. Re:null or not null, that is the question by tritonman · · Score: 1, Insightful

      Please understand there is a difference between a null pointer and a null reference. The difference is very important in C++.

    8. Re:null or not null, that is the question by Chrisq · · Score: 1, Interesting

      Though if you were designing a language you could dissallow the use of ptr as a boolean or numeric value, and force operations like

      if (! valid ptr) {
      }

    9. Re:null or not null, that is the question by RightSaidFred99 · · Score: 1

      Most decent modern languages have exactly this (well, "if (ptr != null)" is required and you can't cast a pointer to a boolean).

    10. Re:null or not null, that is the question by fishbowl · · Score: 2, Interesting

      The C specification already requires the compiler to deal with that, and it's been the case since K&R. No matter what the implementation defines as NULL, comparing or assigning 0 in a pointer context always works.

      http://c-faq.com/null/ptrtest.html

      --
      -fb Everything not expressly forbidden is now mandatory.
    11. Re:null or not null, that is the question by Chrisq · · Score: 1, Informative

      Please understand there is a difference between a null pointer and a null reference. The difference is very important in C++.

      In C++ the difference is purely syntactical, and nothing that a * or a & won't fix.

    12. Re:null or not null, that is the question by Anonymous Coward · · Score: 2, Funny

      When we do hardware debug of chips, we prefer to use a much more visible value such as 0xdeadbeef for instance.

      I've recently seen that one of our developers is using 0xfeedface 0xb00bf00d, which is nice and inventive.

    13. Re:null or not null, that is the question by cant_get_a_good_nick · · Score: 3, Interesting

      RE: malloc pattern initializer

      what's a good one for x86 and AMD64 chips? While spelunking flags for valgrind, i remembered the thought process for 68k chips. Use an A-Line trap, unimplemented so execution would stop. Also, make it odd, so a dereference would trigger a bus error.

      What's the best values for x86 debugging?

    14. Re:null or not null, that is the question by rwrife · · Score: 1

      No, he is at fault for the mistake....at least that's what I'm going to put in our bug tracking system at work.

    15. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      It's hard to imagine life without the null pointer!

      No, it is not. In fact you don't even have to imagine it, there are plenty of languages out there
      which do not allow null pointers. You are right that Hoare is not responsible for the financial loss, in a strictly legal sense, which is why he is not getting sued for it. Morally, however he is responsible.

    16. Re:null or not null, that is the question by locofungus · · Score: 1

      If there is one thing I'll complain about, it's the choice of the value 0

      The choice of the value 0 in the computer is by the compiler, not the C language.

      Infact, on AS400 the null pointer is not all bits zero - which makes a mess of code that attempts to memset structures to zero and then tries to test for null pointers. A pointer with all bits zero is NOT null on that platform.

      Note that if(!ptr) works fine as a test for null, just that:

      memset(&ptr, 0, sizeof ptr); if(!ptr) printf("Ptr is null\n"); else { dereference ptr } will crash.

      ptr=0; if(!ptr) ... is fine.

      Tim.

      --
      God said, "div D = rho, div B = 0, curl E = -@B/@t, curl H = J + @D/@t," and there was light.
    17. Re:null or not null, that is the question by jgtg32a · · Score: 1

      I'm sure HR would love to know you were useing 0xb00bf00d

    18. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      Often, "prefetch" instructions will ignore invalid addresses, null included. Check your architecture manuals.

    19. Re:null or not null, that is the question by marcansoft · · Score: 4, Informative

      Wrong. A NULL pointer is implementation-defined in C and !p would work just as well if the bit value of p were 0xdeadbeef for a NULL pointer. The compiler is responsible for that.

      0 is used because it's convenient for compilers and architectures, not for programmers. Programmers don't care, they never see the bit pattern of a NULL pointer unless they're doing things wrong (casting to integers) or working on lower level architecture-specific code. Most think they do, though. See the C-faq section on NULL pointers.

    20. Re:null or not null, that is the question by renoX · · Score: 1

      [[It's hard to imagine life without the null pointer!]]
      Nobody said that it would be *without* the null pointer, the idea is that a type reference would be non-nullable by default, but when you need it, you would declare your reference as 'nullable'.

      So null is still here, it's just not the default.

      Nice is a language which implement this: you can declare a reference either of type Foo (which means non-nullable) or of type Foo? (which means that the reference can be null).

      Another behaviour by default that C got wrong is initialisation: by default your variables are not initialised so if you forget to initialise your variables your program may act randomly which is a pain to debug, the correct default would be to have all variables initialised by default but with the option to let variables non-initialised which can be useful as a performance optimisation.

    21. Re:null or not null, that is the question by johny42 · · Score: 5, Funny

      That being said, the author is not really responsible for billions of dollars of mistakes, the programmers are.

      Who am I to argue with someone that is taking resposibility for my mistakes?

    22. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      Well a reference is always const e.g. int& const and no amount of *s will change that.

    23. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      If we had an HR department that could perform the 64bit endian conversation required to work out what it spells and we weren't almost entirely staffed with either men, or women who actually have a sense of humour, I'm sure they'd be horrified.

    24. Re:null or not null, that is the question by noidentity · · Score: 1

      If there is one thing I'll complain about, it's the choice of the value 0. It's almost impossible to trace it. When we do hardware debug of chips, we prefer to use a much more visible value such as 0xdeadbeef for instance. Otherwise a bad pointer will bland too much with all the uninitialized values out there.

      There's nothing stopping a C compiler from using 0xDEADBEEF for the internal representation of a null pointer. The fact that 0 can be a null pointer constant in the source text isn't an issue.

    25. Re:null or not null, that is the question by rickb928 · · Score: 2, Interesting

      The first time I saw an ethernet MAC address of 02DEADBEEF20 I went on a 20-minute snipe hunt through the switches.

      It was the /dev/net0 adapter in the standby member of a Sun cluster.

      A month later, I got the inevitable frantic voicemail from the telecom guy, asking what the '^&(*ing 02DEADBEEF20 address' was, and would I pay more attention to these things and secure our network, please and thank you. I told him it belonged to the Teleradiology project, not to worry. He accused me of being an imbecile, that wasn't a legitimate MAC address. I asked him why he hadn't brought this up in any of the weekly meetings for a month, since it was there all along. Hung up on me. I took some time to creat some interesting LAAs for the various minor servers we had, especially the Internet gateway/proxy, and the email server. He was not amused, but his boss was. And told me to stop annoying him. Something about a gun in the monkey cage, if I recall.

      I actually liked the created MAC addresses. Easier to trace. Mundane vendor-supplied MACs are just boring. Hopefully, though, other admins didn't start being creative. There are only so many clever permutations. Thank God for NAT and Token-Ring. Those were the days.

      --
      deleting the extra space after periods so i can stay relevant, yeah.
    26. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      No it's not, a reference can't be NULL.

    27. Re:null or not null, that is the question by SombreReptile · · Score: 1

      When debugging at the hardware level it's fairly common to fill uninitialized memory (or newly allocated in a debug version of the malloc libraries) with a value that will either cause the computer to execute a system level break ( eg: TRAP / BRK etc) or something fairly obvious such as ($BA).

      If you don't like the 0's, then replace your memory allocation library.

      $BA ?
      Does that stand for 'bugger all'?

    28. Re:null or not null, that is the question by Thiez · · Score: 5, Insightful

      > Another behaviour by default that C got wrong is initialisation: by default your variables are not initialised so if you forget to initialise your variables your program may act randomly which is a pain to debug, the correct default would be to have all variables initialised by default but with the option to let variables non-initialised which can be useful as a performance optimisation.

      C did NOT get it 'wrong'. C just gives you a lot of rope to hang yourself with. You are free to write you own version of C that protects you from yourself (tweaking an open source C-compiler to initialise all variables by default (to what value?) should take you a few hours at most, and most of that time will go to finding the right source file to edit...), but I like it when C obliterates my foot every now and then. Alternatively you could write a program that goes through your code to look for situations where variables that may be uninitialised are used (I believe Java does this) and whines about it.

    29. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      "It's hard to imagine life without the null pointer! That being said, the author is not really responsible for billions of dollars of mistakes, the programmers are."

      Full accountabitlity should not be placed on programmers.

      Take engineering codes... If someone messup an engineering code (language structure) to allow an unsafe condition when the codes are followed to the letter then fault rest in those that designed the engineering code (as well as the engineers (programmers) who applied it sinces they didnt do an indepenent check).

      Or lets say Im an engineer who designs manufacturing equipment with codable control. Lets say in the codable control I allow a the pressure in a tank to be set.. SET TankNumber = ThePressure; But for some reason its much easier for me to assume a value will be entered... null values not allowed and should never be used.... Later a programmer messup and writes SET TankNumber ; and the pressure goes crazy blowing up the tank and killing everyone in the room...

      Does the mistake rest fully on the programmer? Of course not.. it was also my fault for allowing such a mistake to be accepted in the program to begin with... Id lose my engineering license at the miniumum.

    30. Re:null or not null, that is the question by ultranova · · Score: 1, Insightful

      Or you could simply define that "!ptr" means "ptr is not a valid pointer" rather than "the value of ptr is 0".

      --

      Forget magic. Any technology distinguishable from divine power is insufficiently advanced.

    31. Re:null or not null, that is the question by mrbobjoe · · Score: 1

      int* ip = 0;
      int& ir = *ip;

    32. Re:null or not null, that is the question by hey · · Score: 1

      I think Microsoft Visual C uses 0xCCCCCCCC.

      But then you have to code:

            if (p != NULL)
            { // Use p
            }

      Instead of:

            if (p)
            { // Use p
            }

    33. Re:null or not null, that is the question by CecilPL · · Score: 2, Informative

      One exists and one doesn't. If you have a Foo&, you're guaranteed that it refers to an actual Foo object. You can't declare "Foo& foo;" without binding it to an instantiated object.

      Of course nothing stops you from have a reference bound to an object that's gone out of scope, but that's different than a "null reference", which doesn't exist.

    34. Re:null or not null, that is the question by LUH+3418 · · Score: 1

      >> the correct default would be to have all variables initialised by default but with the option to let variables non-initialised which can be useful as a performance optimisation

      C was designed at a time when compilers didn't do much in the way of optimization. Hence keywords like "register" and "inline", which are now quite often ignored by the compiler. I would say the best thing would be to initialize variables by default, except when the compiler can prove that a variable does not need to be initialized on creation (ie: the programmer will always initialize it himself before it is used). This way you get most of the performance benefits without the programmer having to think about it (and without the possibility that he might introduce a mistake).

    35. Re:null or not null, that is the question by Amazing+Quantum+Man · · Score: 3, Informative

      Undefined behaviour. A reference must refer to a valid object. Also, dereferencing the null pointer (ip) is undefined behaviour.

      --
      Fascism starts when the efficiency of the government becomes more important than the rights of the people.
    36. Re:null or not null, that is the question by eman1961 · · Score: 1

      I much prefer 0xC0C0BABE to 0xDEADBEEF

    37. Re:null or not null, that is the question by russotto · · Score: 1

      With a zero null value, you can easily arrange for this to happen by protecting the bottom page of memory from reads and writes. That way, even an assembly language program can't dereference a null pointer.

      Until the perennial enemy of safety, performance, rears its head. For a long time (and perhaps still), the IBM POWER XLC compiler would optimize code like


      if (foo && *foo == CONSTANT) ...

      by ignoring the short-circuit and dereferencing the pointer even when it was null. This saves a branch and is apparently a significant time-saver in real-world code, but it does require the zero page be readable.

    38. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      In C++ the difference is purely syntactical, and nothing that a * or a & won't fix.

      Mod parent down, and "misinformative".

      C++ compilers perform compile-time checking to ensure that references are never uninitialized. Once a reference is initialized, it cannot be changed to reference a different object. There are a few other important differences referenced (snark) here: http://en.wikipedia.org/wiki/Reference_(C%2B%2B)

    39. Re:null or not null, that is the question by Carewolf · · Score: 2, Interesting

      You have much to learn. Don't mix how the language is supposed to work and what is actually possible.

      P *p = 0;
      P &r = *p;

      References that are NULL are the worst kind.

    40. Re:null or not null, that is the question by Carewolf · · Score: 1

      Yes, that is exactly what this article is about! Null references, the problem with is that they are give undefined behavior.

    41. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      Please understand there is a difference between a null pointer and a null reference. The difference is very important in C++.

      In C++ the difference is purely syntactical, and nothing that a * or a & won't fix.

      I'm sorry, but you're mistaken. There is a concrete difference between a reference and a pointer.

      A reference is a named alias for a type. It doesn't 'point' to anything, it 'is' the type. It can't be incremented or decremented across memory in the way a pointer can.

      In C++, a reference can not be null because it is nonsense to have an alias name for something that doesn't exist.

      A pointer on the other hand, can point to null in order to identify that it doesn't point to any memory location.

    42. Re:null or not null, that is the question by clone53421 · · Score: 2, Interesting

      How about 0xCC (INT 3), which is typically used as a debug breakpoint? It will halt the execution (as long as you're running the code in a debugger, which is assumed), and it's a one-byte opcode which is good since that means if you somehow jump into unallocated space, you can't jump into the middle of the instruction.

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    43. Re:null or not null, that is the question by thePowerOfGrayskull · · Score: 0

      In C++, a reference can not be null because it is nonsense to have an alias name for something that doesn't exist.

      Yes and no. int * p = 0; int & r = *p; . Perfectly legal and now your reference (r) is null in practice. You can still do "r++" because the "alias name" is valid, but you'll core dump because it's a reference to an invalid memory location.

    44. Re:null or not null, that is the question by clone53421 · · Score: 2, Interesting

      Well, jumping into memory filled with 0xBA would repeatedly execute the instruction 0xBABABA, or MOV DX,0xBABA. I'm thinking that's probably not what GP meant by $BA, but... well, that's all I came up with.

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    45. Re:null or not null, that is the question by thePowerOfGrayskull · · Score: 1

      One exists and one doesn't. If you have a Foo&, you're guaranteed that it refers to an actual Foo object. You can't declare "Foo& foo;" without binding it to an instantiated object.

      Not as correct as you might think.
      void myFooinator(Foo & foo)
      {
      foo.doSomething();
      }
      main()
      {
      Foo * pFoo = NULL;
      myFooinator(*pFoo);
      )
      That's a null reference, and it is legal. Try it and see.

    46. Re:null or not null, that is the question by Anonymous Coward · · Score: 1, Insightful

      cool, great offtopic story about what a huge asshole you are.

    47. Re:null or not null, that is the question by clone53421 · · Score: 1

      Not at all. You're not testing a pointer, you're testing a boolean value. If the type casting is smart enough to check for NULL instead of 0 when converting a pointer to a bool, if(p) will work just fine.

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    48. Re:null or not null, that is the question by belmolis · · Score: 2, Informative

      If that is true, the language compiled by the IBM POWER XLC compiler is not C. The C standard requires short-circuit evaluation of logical and.

    49. Re:null or not null, that is the question by WaywardGeek · · Score: 1

      No, GP is correct. If the compiler knows the contents at address zero, and that it's not equal to CONSTANT, the optimization gives the same answer. It's a peep-hole optimization level thing.

      --
      Celebrate failure, and then learn from it - Nolan Bushnell
    50. Re:null or not null, that is the question by QuackenDuck · · Score: 1

      I never said you couldn't have a null-reference. I only refuted the statement that the difference was "nothing that a * or an & won't fix". So please demonstrate, using all the *'s and &'s you like, an example of an uninitialized C++ reference or a reference that is changed to reference another object.

    51. Re:null or not null, that is the question by jythie · · Score: 1

      That is probably one of the major reasons to make a null pointer zero. Having to store an extra arbitrary value in a register every time you want to check a pointer would probably slow things down quite a bit.

    52. Re:null or not null, that is the question by jythie · · Score: 2, Informative

      While there might be a aesthetic difference in C++, functionally they are identical since a reference is just a pointer with some syntactical sugar to make it look like it isn't.

    53. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      There are important differences. E.g. references can only be assigned once, never reassigned. dynamic_casting references throws exceptions on failure, while failed dynamic_casts on pointer simply yield null pointers. There is no way to assign NULL to a reference in C++ (which seems to be exactly the point that is relevant here).

    54. Re:null or not null, that is the question by jythie · · Score: 1

      *smirk* it isn't supposted to be NULL, but there is nothing stopping one from creating a NULL reference. I think the classic example was something like:

      void foo(string& bar) {}

      baz()

      {

      foo(string(NULL));

      }

      when one tries to access bar in foo, bar is a NULL reference.

    55. Re:null or not null, that is the question by jvkjvk · · Score: 3, Insightful

      Mods are on crack.

      Of course there is more than a syntatic difference between a reference and a pointer in C++.

      For one, references CANNOT be null, while pointers are allowed to be null. I'd say that is an indictor of a pretty big semantic difference, wouldn't you?

      To say that * or & "fixes" the difference is handwaving around the fact that pointers and references are two different, yet related concepts (that is, they have more that a "purely syntatical" difference).

      To be pendatic, you can't even write a null reference in C++; the compiler will complain (more pendantic - although you can delete the underlying object sometimes, this does not make the reference null, merely dangling) so it is also nonsensical to talk about "null references" vis a vis "null pointers" per se, except in a most general way.

      Regards.

    56. Re:null or not null, that is the question by belmolis · · Score: 1

      But what if the contents of address 0 happens to be equal to CONSTANT? In that case the value of the expression will be 1, which is an error.

    57. Re:null or not null, that is the question by jythie · · Score: 1

      That might be the concept of a reference, but in reality a reference is NOT 'the type', it is a pointer that uses . instead of -> notation with a few compile time checks that are pretty easy to get around with casting.
       
      To claim otherwise is just about as useful as defining a 'nocrash' macro and saying that programs that have it don't crash because that would be nonsense, after all, the nocrash flag is set!

    58. Re:null or not null, that is the question by xenocide2 · · Score: 1

      I'm sure it doesn't help things that Stroussoup made this explicit in C++. So if your view is that C is a subset of C++, you'll get these trivia wrong. Unfortunately, C and C++ will penalize you for getting trivia questions wrong with great zeal.

      (And in reading your link, I don't see where it claims that NULL is implementation defined. Perhaps you can offer a more specific citation?)

      --
      I Browse at +4 Flamebait

      Open Source Sysadmin

    59. Re:null or not null, that is the question by Doc+Ri · · Score: 1

      Right. One can also create an undefined reference without explicitly de-referencing a NULL pointer:

      FOO& bar()
      {
          FOO f;
          return f;
      }

      Any decent compiler will issue a warning, though.

      --
      617B3B7F7E7C7D7F00EOF
    60. Re:null or not null, that is the question by JesseMcDonald · · Score: 1

      Alternatively you could write a program that goes through your code to look for situations where variables that may be uninitialised are used (I believe Java does this) and whines about it.

      Most C compilers will do that as well, including GCC, provided you enable the appropriate warnings (either -Wall or -W; I forget which).

      --
      "The state is that great fiction by which everyone tries to live at the expense of everyone else." - Bastiat
    61. Re:null or not null, that is the question by johanatan · · Score: 0

      Actually, null references are not allowed in C++ at all. If you have a reference (i.e., &) then it must be initialized to some non-null.

    62. Re:null or not null, that is the question by Fulcrum+of+Evil · · Score: 1

      Define valid. Seriously, in C, there's no portable value that's always invalid, and it usually depends on the runtime configuration. May as well use null.

      --
      "We returned the General to El Salvador, or maybe Guatemala, it's difficult to tell from 10,000 feet"
    63. Re:null or not null, that is the question by prockcore · · Score: 1

      It should be filled with DAT.F #0,#0

      ... too obscure?

    64. Re:null or not null, that is the question by LordKronos · · Score: 1

      But it is NOT the same answer, as it may generate a runtime exception. You seemed to missed that belmolis said that the C standard REQUIRES the compiler to generate a short-circuit evaluation. It is guaranteed by the language specification that every short-circuit operator be evaluated left to right. There can NEVER be a case where the right side is evaluated when the left side would have been sufficient to determine the outcome. Any compiler that does not follow this rule may be a C-like compiler, but it is not a compliant C compiler. It is not optional.

    65. Re:null or not null, that is the question by Toonol · · Score: 4, Funny

      MOV DX, BABA; GET UP N DANCE

    66. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      language lawyer detected

    67. Re:null or not null, that is the question by LordKronos · · Score: 1

      no, what he's just saying is that if the right side can make the test fail, then the left will not be executed. In your example, he's just saying that it would then followup by checking the left side (which would cause the test to fail).

      However, that is irrelevant, since (as you already pointed out) the C specification says that it can NOT be done that way. Left-to-right evaluation on a short-circuit operator is guaranteed.

    68. Re:null or not null, that is the question by geekgirlandrea · · Score: 4, Informative

      Actually, in C the null pointer constant is a distinct value from integer zero. The standard requires the following (see section 6.3.2.3 of ISO C99):

      • That the integer value 0, when cast to any pointer type, yield a null pointer
      • That a null pointer, when cast to any other pointer type, yield another null pointer
      • That any two null pointers will compare as equal, regardless of type

      As for constructions like if (!ptr), the standard requires that the if statement execute if its value is non-zero, and it would be entirely legal for the null pointer to have a non-zero in-memory representation, but convert to the integer zero. See, for example, the comp.lang.c FAQ.

    69. Re:null or not null, that is the question by Darinbob · · Score: 1

      I work on an embedded system, where dereferencing a null pointer does not cause errors. I had to make the low memory read-only to at least catch writes through null pointers.

      There is also the problem of null function pointers (or with C++, virtual functions). Since I didn't have the granularity to make this region non-executable, I filled the first 256 bytes with 0xdeadbeef. Later I discovered that this was a valid PowerPC instruction, so that bad function pointers wouldn't cause exceptions or traps in the debugger, but just end up branching to the reset routine...

      Another problem I'm seen with 0xdeadbeef, is that everyone uses it. I can't tell if it's the 0xdeadbeef that I assign to unused pointer veriables, or the 0xdeadbeef that Bob filled his stack with, or the 0xdeadbeef that Sue fills all her allocated memory with, etc.

      Back in school there was one student who used a programming technique of not having to check for null pointers by relying on the VAX (BSD) allowing the dereference of address 0. When the school started getting more Suns instead, and the Suns disallowed dereferencing address 0, he complained that the Sun architecture was broken.

    70. Re:null or not null, that is the question by Darinbob · · Score: 1

      Then what happens with a pointer is uninitialized, and happens to have the value of 0 (because that's the default value memory is initialized with), but 0 is no longer the signature of an invalid pointer?

      So you still need some help from the system to catch these pointers to low memory. You could also initialize memory (and new pages) with invalid pointers too I suppose, but I see too much software that implicitly assumes all of memory is initialized to zeros.

    71. Re:null or not null, that is the question by SanityInAnarchy · · Score: 1

      I like it when C obliterates my foot every now and then.

      Why?

      --
      Don't thank God, thank a doctor!
    72. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      >Alternatively you could write a program that goes through your code to look for situations where variables that may be uninitialised are used (I believe Java does this) and whines about it.

      that's called lint

    73. Re:null or not null, that is the question by Guy+Harris · · Score: 1

      No, GP is correct. If the compiler knows the contents at address zero, and that it's not equal to CONSTANT, the optimization gives the same answer. It's a peep-hole optimization level thing.

      No, the poster in question is incorrect. If a particular implementation of C happens to represent the null pointer constant in a fashion that makes it look like a pointer to location X, then the C compiler is obliged to arrange that no object live at that location, so, in this particular case, the contents at address zero are irrelevant.

    74. Re:null or not null, that is the question by Guy+Harris · · Score: 1

      Not at all. You're not testing a pointer, you're testing a boolean value. If the type casting is smart enough to check for NULL instead of 0 when converting a pointer to a bool, if(p) will work just fine.

      Well, not exactly. If we're talking C, there's no notion of a "boolean" expression; the part of C that makes it work is that:

      1. !p means the same thing as p != 0;
      2. 0, when used to assign to or compare with a pointer, is not the integral constant 0, it's the "null pointer constant", which is a constant pointer value that is unequal to the address of any C object.
    75. Re:null or not null, that is the question by Guy+Harris · · Score: 2, Informative

      I think Microsoft Visual C uses 0xCCCCCCCC.

      No, it represents a null pointer as an all-bits-zero value, as do almost all other C implementations.

      But then you have to code:

      No, you don't. In the C Programming Language, if p is a pointer, then !p, p != 0, and p != NULL mean the same thing, regardless of how null pointers are represented.

    76. Re:null or not null, that is the question by jc42 · · Score: 1, Interesting

      Of course there is more than a syntatic difference between a reference and a pointer in C++.
      For one, references CANNOT be null, while pointers are allowed to be null.

      This reminds me of an embedded project that I worked on some years ago, that was mostly coded in C. For reasons having to do with the CPU and its hardware memory mapping, we found it handy to have a global variable declared as "extern unsigned char* physmem;", whose address was defined during linking to be zero. I was duly impressed by the fact that the C compiler wasn't fazed by this, and handled it correctly. I.e., the value of &physmem was numerically zero, the same as a null pointer. This allowed us to use physical memory as "just a byte array", and eliminated the need for clumsy special-purpose code for dealing with this one special byte array.

      If it's true that C++ doesn't allow this, then that excludes the use of C++ on hardware with such properties. Of course, people working at the level that we were generally wouldn't take you seriously if you suggested C++. We had enough trouble convincing some of them that the work should be done in C rather than assembly language ("as God intended", where "God" was the name of the committed that designed the hardware ;-). If C had imposed such silly restrictions, the job probably would have been done in assembly.

      --
      Those who do study history are doomed to stand helplessly by while everyone else repeats it.
    77. Re:null or not null, that is the question by ultrabot · · Score: 1

      He accused me of being an imbecile, that wasn't a legitimate MAC address. I asked him why he hadn't brought this up in any of the weekly meetings for a month, since it was there all along. Hung up on me. I took some time to creat some interesting LAAs for the various minor servers we had, especially the Internet gateway/proxy, and the email server. He was not amused, but his boss was. And told me to stop annoying him.

      Lound like a real-life BOFH story. Not that there is necessarily anything wrong with that ;-).

      --
      Save your wrists today - switch to Dvorak
    78. Re:null or not null, that is the question by ZiggyM · · Score: 1

      The "more" correct way to write such code is: if (ptr!=NULL){...} Ive worked at proyects where that was enforced. It really doesnt matter in C because NULL is defined to be zero, but its better to use "ptr!=NULL" anyways, since ptr is not a boolean value. Its an abuse of the fact that NULL==0 to write "!ptr".

    79. Re:null or not null, that is the question by eint · · Score: 1

      very true... though I prefer these differences null pointer: much more dangerous because of the sharp points that can jab and stab null reference: talking about someone or something that doesn't really matter Or perhaps a killer book reference: http://nullpointer.ning.com/

    80. Re:null or not null, that is the question by adisakp · · Score: 1

      Just out of curiosity sake, although the standard allows NULL pointer to have storage other than zero, is there any real world compiler where this is true?

      If so, it would break most code that uses unions with pointers for storage (i.e. load-in-place fixups) and code that relies on extra bits and bit-patterns shared with pointers (i.e. lots of lockfree code stuffs data into what is assumed to be unused bits in pointers). It would probably break a lot of code that uses pointer math as well -- for example, anything using an "offsetof()" style macro.

      Basically, I think that people have to KNOW that NULL is going to be represented as 0 (by their compiler) to write some of the code that actually is used in the production world. Any compiler that didn't do this would break so much code that it would not be usable by the general coding population.

    81. Re:null or not null, that is the question by clone53421 · · Score: 1

      Well, I think I assumed "Microsoft Visual C++" was what was meant. Is there any such thing as "Microsoft Visual C"?

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    82. Re:null or not null, that is the question by wiredlogic · · Score: 2, Informative

      NULL has always been implementation defined. The whole reason why the macro was put into ANSI C was to move people away from the practice of casting a 0 into a pointer as was done with K&R C. While rare today, there have been commercial computers that didn't use 0 for the null address. The comp.lang.c FAQ lists some of them.

      Stroustrup's unwillingness to implement a null keyword is the biggest single flaw in C++. It's pretty silly to pepper your code with magic 0's when the compiler could very well be changing them to something else if the target platform uses a different convention for nulls. It completely flies in the face of the type safety mechanism in C++ to have this sort of automatic conversion of a literal integer into something else that is decidedly *not* an integer.

      Considering all the cruft that has been bolted onto C++, it's really annoying that B.S. couldn't see the wisdom of having a "null" keyword (or "_Null" a la C99 "_Bool").

      --
      I am becoming gerund, destroyer of verbs.
    83. Re:null or not null, that is the question by doti · · Score: 1

      `gcc -Wall -Wextra -Werror` will check for uninitialized variables.

      --
      factor 966971: 966971
    84. Re:null or not null, that is the question by xenocide2 · · Score: 1

      The good news is that, as my link points out, C++0x will have a nullptr keyword to replace 0.

      --
      I Browse at +4 Flamebait

      Open Source Sysadmin

    85. Re:null or not null, that is the question by Jamie+Lokier · · Score: 1

      it would break most code that uses unions with pointers for storage (i.e. load-in-place fixups) and code that relies on extra bits and bit-patterns shared with pointers (i.e. lots of lockfree code stuffs data into what is assumed to be unused bits in pointers).

      A lot of architectural quirks break that sort of code. And yes, that sort of code does break on some architectures. You've put your finger on why all the popular architectures have pointers being simple numbers, though.

      Interesting that you pick that out, because that's one thing that non-zero NULL doesn't have to break - as long as it has the same alignment and range as a regular pointer, your tricks with extra bits work ok.

      It would probably break a lot of code that uses pointer math as well -- for example, anything using an "offsetof()" style macro.

      Actually no. Pointer math isn't affected by the representation of NULL, as you're never going to add an offset to NULL and dereference the result, are you? And you never add pointers to each other, because it makes no sense. offsetof() is fine too - it can be defined in the system header file in an appropriate way.

      Still, there are things that don't work as expected if NULL isn't zero. Things like memset(&x, 0, sizeof(x)) and expecting the pointers in x (a structure) to be NULL, that's quite common.

    86. Re:null or not null, that is the question by JackStrife17 · · Score: 2, Insightful

      >I like it when C obliterates my foot every now and then.

      Once again reinforcing the stereotype that people who enjoy programming in C are masochists at heart.

    87. Re:null or not null, that is the question by shutdown+-p+now · · Score: 1

      (And in reading your link, I don't see where it claims that NULL is implementation defined. Perhaps you can offer a more specific citation?)

      ISO/IEC 14882:2003(E), 3.9.2[basic.compound], p.3:

      "The value representation of pointer types is implementation defined."

      Note furthermore that C++ spec makes the following two have different meaning:

      void* p = 0; // okay, p is a null pointer
       
      int i = 0;
      void* p = (void*)i; // the value of p is implementation-defined, need not be null

    88. Re:null or not null, that is the question by rickb928 · · Score: 1

      It was job satisfaction. Not mention the telecom guy was fabulously clueless about networking, and had the odd habit of updating switch firmware on Friday afternoons, and blowing it up regularly. I bet he still thinks TFPT stands for Terminal File Transfer Protocol. He kept trying to use the TFTP process by typing 'tftp' at his terminal session. And then asking me where the documentation was for the process.

      And I never even *leaned* against his switch, or messed with his telco stuff. He was the one chewing gum in the machine room and dropping flecks of tinfoil into the server chassis. All that got me was a scornful look and 'it couldn't be me' while he was chawing on another cud of Juicy Fruit.

      He didn't have enough to do. I made his work more interesting. Nothing got broken, except *maybe* his heart, and I doubt that. At least he knew Token-Ring before I left.

      BOFH. I like that. It sure beats being an AC.

      What acronym for 'clueless'?

      ps- he would flash anything I might have to fix on a Friday afternoon. He didn't do that to his stuff. Telephones are more important, it seems.

      --
      deleting the extra space after periods so i can stay relevant, yeah.
    89. Re:null or not null, that is the question by thethibs · · Score: 1

      Actually, you start by checking the list length. If it's zero, you do whatever is spec'd for an empty list. If the length is non-zero and the pointer is zero, that's a wtf fatal error.

      --
      I'm a Programmer. That's one level above Software Engineer and one level below Engineer.
    90. Re:null or not null, that is the question by Carewolf · · Score: 1

      While it is true there is no simple way to reassign a value of a reference because the '&' operator acts as id-operator on references, it still can be uninitialized, simply by "initializing" it to an uninitialized pointer:


      Object *p;
      Object &r = *p;

    91. Re:null or not null, that is the question by 7+digits · · Score: 2, Informative

      > I'm sure it doesn't help things that Stroussoup made this explicit [att.com] in C++. So if your view is that C is a subset of C++, you'll get these trivia wrong. Unfortunately, C and C++ will penalize you for getting trivia questions wrong with great zeal.

      You are wrong on two counts: first, his name is Stroustrup. Second, in C++, like in C, the literal 0 in a pointer context will be turned into the NULL pointer by the compiler.

      void *p = (void*)0;

      p will be a NULL pointer

      int a = 0;
      void *p = (void *)a;

      p may not be a NULL pointer, as the 0 was not a literal in a pointer context.

      Hence,

      if (p)

      means:

      if (p==0)

      so, if p is a pointer type, it means:

      if (p==(void*)0)

      which means

      if (p is the NULL pointer)

      The NULL pointer can be represented internally by whatever bitpattern or trick that the compiler writer wants.

    92. Re:null or not null, that is the question by QuackenDuck · · Score: 1


      Object *p;
      Object &r = *p;

      Nonsense. 'r' has, indeed, been initialized. That you've initialized it with an invalid object makes 'r' no less initialized.

      Additional compile-time checking is done on references that are not done on pointers. This is enough to call into question the OP's statement that the differences between pointers and references are 'purely syntactical'. That has been my beleaguered point all along.

      Smug programmers who "break" references with cleaver code only demonstrate that they don't understand references and does not devalue the compile-time protection that references provide. The longer the myth that references and pointers are the same is perpetuated, the longer those programmers will wallow in ignorance.

    93. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      $BA trigged an old memory of 0xbadcafe and 0xdeadbeef

      Also I seem to recall Enforcer and Mungwall. Please straighten me up!

    94. Re:null or not null, that is the question by fava · · Score: 1

      If the author had not invented them, someone else would have. He is not the cause of the problem, merely the first to implement them.

    95. Re:null or not null, that is the question by forgoil · · Score: 1

      *cringe*

      Null references makes me sad sad sad. People creating them on purpose (not that you did, as that was an example) makes me unhappy.

      To add to the above poster, null references are not just the worst kind, but would render you a stern lecture from someone like me if you ever tried it in a real product.

    96. Re:null or not null, that is the question by andy_t_roo · · Score: 1

      unless they're doing things wrong (casting to integers)

      but casting to char[4] is quite usefull when rendering to a screen - there's nothing like doing hit detection with a rendering pass, grabbing the colour of the pixel you clicked on, then calling the colour cast to a function pointer :)
      (oh, and then discovering that a specific implementation of opengl lies about the availability of an alpha channel, so the 4th byte is always 0 .... )

    97. Re:null or not null, that is the question by Yunzil · · Score: 1

      Just out of curiosity sake, although the standard allows NULL pointer to have storage other than zero, is there any real world compiler where this is true?

      Read this

      If so, it would break most code that uses unions with pointers for storage (i.e. load-in-place fixups) and code that relies on extra bits and bit-patterns shared with pointers (i.e. lots of lockfree code stuffs data into what is assumed to be unused bits in pointers). It would probably break a lot of code that uses pointer math as well -- for example, anything using an "offsetof()" style macro.

      I don't see why a non-zero NULL would break any of that, especially the offsetof() thing?

    98. Re:null or not null, that is the question by Chaostrophy · · Score: 1

      There was hardware that had a negative zero that could not be arrived at mathematically, it had to be assigned. You could use it for initializing arrays, and thus just by checking the value, determine if an element had been written to.

      --
      Plato seems wrong to me today
    99. Re:null or not null, that is the question by CTalkobt · · Score: 1

      Actually, as GP poster, I meant any value such as $BA or whatever is common with Intel. My assembly background primarily involves the 6502 (old) and it's BRK value is not relevant towards this conversation (BRK = $00 ) :-(

      --
      There's a gorilla from Manilla whose a fella that stinks of vanilla and has salmonella.
    100. Re:null or not null, that is the question by ncmathsadist · · Score: 1

      You are responsible for initializing variables in C. If you don't that is your fault.

    101. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      You can't avoid "doing things wrong (casting to integers)" when you write an operating system in C, and depending on the operating system it (I don't pretend I know them all) you won't even limit such casts to the lower level architecture-specific code.

      As a more general remark you can not write an operating system in C without interacting with non standard extensions of you compiler. Representation of pointers is very very basic in this context.

    102. Re:null or not null, that is the question by fractoid · · Score: 1

      Now we're getting somewhat abstract. Does the C standard say that "left to right short circuit evaluation must take place" (stipulating the actual operations performed by the CPU), or does it simply dictate how the code will function logically? (ie. "the code must perform as if the conditions had been evaluated left to right in short-circuit fashion"). The latter would allow optimisations such as performing both tests in parallel IF neither has any side effects (which often is the case).

      --
      Rampant carbon sequestration destroyed the Dinosaurs' tropical paradise. I'm here to help repair the damage.
    103. Re:null or not null, that is the question by honkycat · · Score: 1

      Automatic initialization sounds great, but it doesn't address the problem. The problem is that if you're trying to read a value before you set it, you have flawed code. Unless you know something about the algorithm, it's hard to predict a good value to start with. I think the right approach is the fail-fast approach -- if possible, refuse to compile code that doesn't guarantee initialization. Anything else just hides programming errors...

    104. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      !p and p==0 are well defined for pointers (both always check for null). The 0 is being used as a null pointer literal, not an integer which happens to use the right bits. In fact you can't set an integer to zero at runtime and reliably get a null pointer by casting it, only a 0 in the source code works this way. #define NULL 0 is legal and always works, though some compiler vendors add a cast or something just for better error messages.

    105. Re:null or not null, that is the question by Atario · · Score: 1

      Or you could use C#, where not initializing your variables before using them is simply a violation of the language specification.

      --
      "A great democracy must be progressive or it will soon cease to be a great democracy." --Theodore Roosevelt
    106. Re:null or not null, that is the question by mrbobjoe · · Score: 1

      Fair enough, that example relies on pointer dereferencing. As you say references must refer to a valid object, and for the most part this is enforced by requiring them to be initialized.
      While it's circuitous to have a never valid reference, it isn't particularly unlikely:

      struct A {
              int& ir1;
              int& ir2;
              A(int& i) : ir1(ir2), ir2(i) {}
      };

      With enough warnings enabled g++ warns about this, but I don't think it's the "don't compile this" kind of illegal but rather the "certain failure at runtime" kind, like any uninitialized variable. Likewise the simple:

      int& f() {
              int i;
              return i;
      }

      Undefined, but no more forbidden than taking the address and returning it.

      Your point that it causes "undefined behaviour" is exactly my point, were references properly constrained by the language this would be outright illegal, not merely undefined. Of course I haven't read the standard or Stroustrup closely enough to be able to cite anything so fire at will.

    107. Re:null or not null, that is the question by canix · · Score: 1

      Rubbish.

      The C standard states that "!E" is the same as "E == 0" and that 0 is the null pointer constant. There is nothing "more" correct about what you are claiming.

    108. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      FWIW, one can observe that a C++ reference is very similar to a constant pointer in C; both must be assigned at compile time, but they can be assigned undefined values.

      e.g. int * const ref = &x; /* ref is a constant pointer to a non-constant integer (i.e. x) */

    109. Re:null or not null, that is the question by mgiuca · · Score: 1

      This is correct.

      But an important detail you left out: The constant NULL is defined as the integer value 0. Therefore, casting NULL to a pointer results in the null pointer.

      It's important (or is it?) to realise that the null pointer's bit pattern is not necessarily 0. It can be anything. But NULL is 0. If your C compiler decides for the null pointer's bit pattern to be nonzero, then the cast operation from an into to a pointer has to convert the integer value 0 to the null pointer's bit pattern.

      Obviously, most C implementations, for simplicity, choose the same bit pattern as the integer 0 for the null pointer, so intpointer casts are no-ops.

    110. Re:null or not null, that is the question by LordKronos · · Score: 1

      But the whole reason this topic came up was because the compiler in question generated code that required the hardware to be configured in a certain way. Yet the reason it had to be configured that way was because the instructions generated for code on the right side of a short-circuit test required it, even though the code on the left side dictated that no such requirement should exist. If the short circuit evaluation were properly adhered to, then no such requirement on system configuration would be in place.

      Thus we are clearly talking about 2 completely different results. It is not equivalent code. There is a side effect of doing it differently, and that's the basis that some of us have been arguing from.

      There is no question that the underlying hardware can do things in whatever way it wants as long as the result is the same. Look at modern CPUs that do predictive branching. They will guess at what the outcome of a branch will be even before the result is known, and they will then execute the code on the predicted branch before the result is known. When the result is finally known, if it turns out the hardware guessed wrong, then the code from the predicted branch is flushed from the pipeline without ever being committed. The end result is exactly the same as if the prediction had not taken place. That's an equivalent result. It is transparent (other than some performance implications, but performance isn't dictated by the C spec).

    111. Re:null or not null, that is the question by specu · · Score: 1

      Guys, we are not talking about null pointers but null references in general, doesnt matter if its C/C++ NULL pointer or null reference in C#/Java. Null references are not _needed_ Most of the times there are used: - as return values from functions to denote failure, exceptions should be used - lazy initialization when the state is preserveed somewhere and we dont want to create an empty object, polymorphic wrapper data type should be used Null pointers exists because of Object Oriented paradigm which is governed by states, and you need to have ability to say that a state is invalid. It is not a feature of allocation library or execution enviroment In functional world and languages like OCaml or Haskell, there is no requirment of having null references, there could be and empty list or special type wrapping above cases (option in ocaml and Maybe in Haskell). This monad allows also to push code checks against the value into the monad itself, using higher order function (which will be passed into combinator and only called when the value of the type is not `null') Most of the cases when code fails with huge bang, exception or seamlessly doesnt execute is determined by existences of null pointers.

    112. Re:null or not null, that is the question by oiron · · Score: 1

      ...(to what value?) ...

      I think that pretty much sums up that idea... Working in nearly-machine level that C does, you can't make assumptions of the safety of a particular value. Especially in the case of something like MMIO, for example... You might just be initializing a piece of memory to an instruction that says "Launch all thermonuclear missiles at random targets"...

    113. Re:null or not null, that is the question by hey · · Score: 1

      Just to follow up.

      I meant Microsoft Visual C++.

      It seems it uses 0xCCCCCCCC for uninitialized memory not NULL pointers. Sorry about that.

      Here's an article on it:
      http://www.codeguru.com/Cpp/W-P/win32/tutorials/article.php/c9535/

      Maybe it you try to follow a NULL pointer you end up at uninitialzed memmroy. eg printf("hello %x", *NULL);

    114. Re:null or not null, that is the question by jgrahn · · Score: 1

      The "more" correct way to write such code is: if (ptr!=NULL){...} Ive worked at proyects where that was enforced. It really doesnt matter in C because NULL is defined to be zero, but its better to use "ptr!=NULL" anyways, since ptr is not a boolean value. Its an abuse of the fact that NULL==0 to write "!ptr".

      How can it be abuse to do something which is readable, widely used and guaranteed to work just as well as the longer version? I suspect people who prefer if(p!=NULL) to if(p) had an early love affair with some other language with a different type system, which they never really got over.

      That said, I can tolerate if(p!=NULL) if needed. if(something==TRUE), on the other hand ...

    115. Re:null or not null, that is the question by Guy+Harris · · Score: 1

      Maybe it you try to follow a NULL pointer you end up at uninitialzed memmroy. eg printf("hello %x", *NULL);

      If you try to follow a null pointer on any Win32 (or presumably Win64) environment, at least the ones from Microsoft (and probably in WINE and ReactOS as well), you end up at a page mapped out of your address space, and probably get a trap/fault/signal/exception, just as you do on most versions of UN*X - at least as long as the offset from that pointer to which you're referring isn't large enough that you get past the end of the unmapped region. Most structures are probably small enough that you'll refer to the unmapped region; I guess if you have a pointer to a large-enough array and use a large-enough array index you could end up in a mapped region, although that'll probably be a read-only code region so you might still get a fault if you store into that region. (I don't know offhand how address space randomization would affect that.)

    116. Re:null or not null, that is the question by ZiggyM · · Score: 1

      Ok, I also use "if (!ptr)", but what I meant is that is "more" correct because the algorithm would be more easily portable to another language. Of course it will always work in C because it guarantees NULL===0. But writting (!p) involves a hidden cast to a boolean operator, while (p!=NULL) does not, and it ports to other languages.

    117. Re:null or not null, that is the question by bored · · Score: 1

      As the parent said, there is a difference between a reference and a pointer, what you are describing is a pointer, and your syntax continues to work just fine in C++.

    118. Re:null or not null, that is the question by jgrahn · · Score: 1

      Of course there is more than a syntatic difference between a reference and a pointer in C++. For one, references CANNOT be null, while pointers are allowed to be null.

      This reminds me of an embedded project that I worked on some years ago, that was mostly coded in C. [...] a global variable declared as "extern unsigned char* physmem;", whose address was defined during linking to be zero. [...] If it's true that C++ doesn't allow this, then that excludes the use of C++ on hardware with such properties.

      Who said that it doesn't? The grandparent was talking about C++ references which (as he pointed out) are not pointers. C++ allows it just as much as C does (i.e. it works in many environments with flat memory, but the language doesn't formally support it). But it doesn't seem like a great idea; you could probably use C++ and come up with a faster, clearer and less unsafe way to access your hardware registers.

    119. Re:null or not null, that is the question by jgrahn · · Score: 1

      Another behaviour by default that C got wrong is initialisation: by default your variables are not initialised so if you forget to initialise your variables your program may act randomly which is a pain to debug, [...]

      As opposed to having variables initalised by default, so your program can act randomly when the default value is not suitable in your scenario, and you forgot to initialise your variables? The compiler wouldn't even be able to help you by issuing warnings about uninitialized variables, and neither would valgrind or similar tools.

      C++ solves that by letting you define your own types with cheap, user-defined, type-specific enforced initialization, i.e. constructors.

    120. Re:null or not null, that is the question by adisakp · · Score: 1

      I don't see why a non-zero NULL would break any of that, especially the offsetof() thing?

      So you're saying this would work still if NULL pointers were not zero? Remember, if you have a nonzero NULL, casting 0 to a pointer results in some nonzero value (say like 0xdeadbeef).

      struct foo { int a,b,c; };
      #define offsetof(obj,fld) ((int)(&(((obj*)0)->fld)))
      printf("The offset of c is 0x%08x",offsetof(foo,c));


      The above prints out "The offset of c is 0x00000008". Change NULL to 0xdeadbeef and the above prints out "The offset of c is 0xdeadbef7".

    121. Re:null or not null, that is the question by adisakp · · Score: 1

      Actually no. Pointer math isn't affected by the representation of NULL, as you're never going to add an offset to NULL and dereference the result, are you?

      So you're saying this would work still if NULL pointers were not zero? Remember, if you have a nonzero NULL, casting 0 to a pointer (i.e. ((obj*)0) ) results in some nonzero value internally (say like 0xdeadbeef).

      struct foo { int a,b,c; };
      #define offsetof(obj,fld) ((int)(&(((obj*)0)->fld)))
      printf("The offset of c is 0x%08x",offsetof(foo,c));


      The above prints out "The offset of c is 0x00000008". Change NULL to 0xdeadbeef and the above prints out "The offset of c is 0xdeadbef7".

      And you never add pointers to each other, because it makes no sense. offsetof() is fine too - it can be defined in the system header file in an appropriate way.

      There times where I have seen code reinterpret a pointer of one type and end up doing pointer math with a different type. A simple enough example is a hack that's often used to allocate a single buffer large enough to contain several different objects. We had a guy here write a memory system that checked for buffer overflows by using a front-porch / back-porch data buffers that would often catch corruption. Internally, the memory system did something similar to this:

      MemLink *pa; MemFrontPorch *pb; MemBackPorch *pc;
      pa=(MemLink *)malloc(sizeof(*pa)+sizeof(*pb)+sizemem+sizeof(*pc));
      pb=(MemFrontPorch *)(pa+1); pc=(MemBackPorch *) (((int)(pb+1))+sizemem);


      There you have code doing math with dissimilar pointers (albeit incrementally) but "pc" does end up being the result of pointer math from a pointer of "MemLink" and "MemFrontPorch".

    122. Re:null or not null, that is the question by Anonymous Coward · · Score: 0

      Or just turn on warnings in your damn compiler

    123. Re:null or not null, that is the question by Jamie+Lokier · · Score: 1

      Actually no. Pointer math isn't affected by the representation of NULL, as you're never going to add an offset to NULL and dereference the result, are you?

      So you're saying this would work still if NULL pointers were not zero?

      Yes.

      Remember, if you have a nonzero NULL, casting 0 to a pointer (i.e. ((obj*)0) ) results in some nonzero value internally (say like 0xdeadbeef).

      (obj*)0) results in a null pointer of type "obj*". It's still a null pointer, will still evaluate to false in boolean contexts, will still compare equal to "0". The internal representation does not matter in most circumstances.

      struct foo { int a,b,c; };

      #define offsetof(obj,fld) ((int)(&(((obj*)0)->fld)))

      printf("The offset of c is 0x%08x",offsetof(foo,c));

      The above prints out "The offset of c is 0x00000008". Change NULL to 0xdeadbeef and the above prints out "The offset of c is 0xdeadbef7".

      This is why you should use the compiler's offsetof() macro defined in <stddef.h>. Writing your own, wrongly, is asking for trouble :-)

      (I admittedly do exactly that :-) But only on platforms where offsetof() isn't defined or doesn't work)

      It has been pointed out that your macro is allowed to work even on a compiler with non-zero-representation null pointers. That's because dereferencing ((obj*)0)->field has implementation defined behaviour anyway (it's a null pointer so it's special), so the compiler is allowed to return the offset.

      And you never add pointers to each other, because it makes no sense. offsetof() is fine too - it can be defined in the system header file in an appropriate way.

      There times where I have seen code reinterpret a pointer of one type and end up doing pointer math with a different type. A simple enough example is a hack that's often used to allocate a single buffer large enough to contain several different objects. We had a guy here write a memory system that checked for buffer overflows by using a front-porch / back-porch data buffers that would often catch corruption. Internally, the memory system did something similar to this:


      MemLink *pa; MemFrontPorch *pb; MemBackPorch *pc;

      pa=(MemLink *)malloc(sizeof(*pa)+sizeof(*pb)+sizemem+sizeof(*pc));

      pb=(MemFrontPorch *)(pa+1); pc=(MemBackPorch *) (((int)(pb+1))+sizemem);

      There you have code doing math with dissimilar pointers (albeit incrementally) but "pc" does end up being the result of pointer math from a pointer of "MemLink" and "MemFrontPorch".

      That's something completely different. There are no pointers being added to each other there. Just integers added to non-null pointers remaining inside an allocated object, and casts between pointers to different structs. Both those things are required to work even on obscure C machines (but make sure the structures have sufficient alignment/padding, otherwise they'll break even on common machines). See the C language FAQ.

    124. Re:null or not null, that is the question by adisakp · · Score: 1

      I would still like to see you point out just one real-world production-ready C compiler where NULL is not internally represented by 0 and then try out those cases by myself. First of all, I'm not aware of any NULL!=0 (internal representation) compilers and I'm pretty sure if you found one, I could in turn find lots of real-world code that would break on it (either from the code or the compiler failing to follow standards)..

    125. Re:null or not null, that is the question by Jamie+Lokier · · Score: 1

      Of course some real world code breaks. Less than you'd think, but enough to matter.

      But then a lot of real world code on GNU/Linux breaks if you use the wrong version of GCC, especially on a non-x86 architecture, let alone a different compiler than GCC...

      I'm not aware of any currently actively used C compilers where NULL has non-zero representation. There used to be quite a few. The C language FAQ mentions why they were abandoned - because C coders tended to assume an all-zeros representation, which is nearly always invisible (as we've discussed), but occasionally matters.

      I've no idea what the C/C++ compilers for .NET use to represent NULL. Choices of compilers: Microsoft, GNU (cscc) and lcc (lcc.net).

    126. Re:null or not null, that is the question by neomunk · · Score: 1

      I think you're looking for something like this list here.

    127. Re:null or not null, that is the question by renoX · · Score: 1

      >so your program can act randomly when the default value is not suitable in your scenario

      Your program won't act randomly, even if it's the wrong result at least you have a consistent/coherent behaviour which allow easy troubleshooting.

      The default value assigned to a variable could be to a special 'unitialised value' but due to current CPU this has an hight performance cost..

      >C++ solves that [cut]

      No, it doesn't as this works only for user-defined types, and 'base type' are still quite used in C++ so this is only a very partial solution..

    128. Re:null or not null, that is the question by olsson · · Score: 1

      Not legal

      ISO C++ standard - section 8.3.2 paragraph 4

      "A reference shall be initialized to refer to a valid object or function.
      [Note: in particular, a null reference cannot exist in a well-defined
      program, because the only way to create such a reference would be to bind it
      to the ``object'' obtained by dereferencing a null pointer, which causes
      undefined behavior."

    129. Re:null or not null, that is the question by Yunzil · · Score: 1

      Then you're doing it wrong.

      #define offsetof(obj,fld) ((size_t)((char *)&((obj *)0)->fld - (char *)0))

  2. 20 second explanation by AKAImBatman · · Score: 4, Interesting

    I am having trouble of grokking null-reference free language.

    If you're familiar with SQL, then a simple "MyColumn NOT NULL" definition should explain it. Basically, the value can never be set to a null value. Attempting to do so is an error condition itself.

    In fact, DB design is a pretty good analogy for the concept as databases often are forced to wrestle with this issue.

    Consider for a moment how you would design a database that has absolutely NO null references. Not a one. Zip, zero, nada. Obviously the best way of accomplishing such a database is to denormalize any value that might be null. So if Address2 is optional, you would want to split Address into its own table with a parent key pointing back to the user entry. If the user has an Address2 value, there will be a row. If the user does NOT have an Address2, the row will be missing. In that way, empty result sets take the place of null values.

    In terms of programming languages, there are a varity of ways to map such a concept. Collections are a 1:1 mapping to result sets that can work. If you don't have any values in your collection, then you know that you don't have a value. Very easy. Similarly, you can be sure that none of the values passed to a function or method will ever contain a null value. Cases where you might want to pass some of the values but not all can be handled either by method overloading (e.g. Java) or by allowing a variable number of parameters. (e.g. C)

    Some pieces of programming would become slightly more difficult. For example, 'if(hashmap.get("myvalue") != null)' would not be a valid construct. You'd need to perform a check like this: 'if(hashmap.exists("myvalue")'

    Of course, the latter is the "correct" check anyway, so the theory goes that the software will be more robust and reliable.

    1. Re:20 second explanation by Anonymous Coward · · Score: 3, Insightful

      doesn't NULL in SQL represent "unknown", which is something entirely different that a NULL reference, which in the context of programming languages is a discrete value?

    2. Re:20 second explanation by MattRog · · Score: 5, Informative

      "Obviously the best way of accomplishing such a database is to denormalize any value that might be null"

      That's normalizing -- the table in this example is de-normalized

      --

      Thanks,
      --
      Matt
    3. Re:20 second explanation by Sockatume · · Score: 1

      You lost me at "simple". Sorry. I'm afraid I don't grok what a null reference is to begin with, which may be an issue.

      --
      No kidding!!! What do you say at this point?
    4. Re:20 second explanation by AKAImBatman · · Score: 1

      Derr... haven't had my coffee yet. Thanks for pointing that out so that no one gets confused. :-)

    5. Re:20 second explanation by MattRog · · Score: 1

      No worries -- the concept is right :)

      --

      Thanks,
      --
      Matt
    6. Re:20 second explanation by AKAImBatman · · Score: 4, Informative

      doesn't NULL in SQL represent "unknown", which is something entirely different that a NULL reference

      No. NULL in SQL represents an absence of data. Which is occasionally used to cover for unknown values. However, NULL is a piece of data that says there is an absence of data. Which is incorrect. Absence of data means that it doesn't exist. Therefore, nothing should exist in its place.

      Normalizing the database can create a situation where the NULL is unnecessary. Therefore, the concept is not needed by computer science. The problem is that real-world considerations often override the ivory tower of comp-sci. And one of those considerations was the fact that RDBMSes have traditionally been organized according to a fixed column model. The inflexibility of the model is driven by the on-disk data structures which are optimized for fast access. OODBMSes (which are really fancy RDBMSes with many "pure" relational features that work around the traditional weaknesses of RDBMSes) attempt to solve this issue by introducing concepts like table-less storage, columns that may or may not exist on a per-row basis, and a dynamic typing system that potentially allow for any data type to show up in particular column. (Note that columns are often handled more as key-value pairs than what we normally think of as columns. This does not undo the theoretical foundation of the Relational model, only results in a different view on it.)

    7. Re:20 second explanation by Omnifarious · · Score: 1

      My problem is that null references are typically used to signal the ends of lists or the place where the tree ends.

      I could see using a variant type for this. Instead of pointing to null, the next to the last list element would point to a value that had the type 'last list element' and no pointer inside it. And there would be four varieties of tree node, leaf, left filled, right filled and both filled.

      Can you think of any better ways than that to handle the lack of a null reference when building data structures? That solution seems sort of ridiculously complex on non-OO languages, and a pain even for OO languages.

    8. Re:20 second explanation by sunking2 · · Score: 1

      Please don't try to explain the behavior of an actual language with SQL. Its demeaning.

    9. Re:20 second explanation by Vellmont · · Score: 1


      doesn't NULL in SQL represent "unknown",

      Sorta. From an operational perspective it represents an un-initialized state. If you don't write anything to a particular column, it's null. From a set-theory perspective it represents "nothing".

      which is something entirely different that a NULL reference, which in the context of programming languages is a discrete value?
      No. I'd say that NULL in a programming language is largely the same concept. Doesn't exist, nothing, etc. It's perhaps slightly more broad, since programming languages aren't just sets.

      --
      AccountKiller
    10. Re:20 second explanation by pi_rules · · Score: 1

      Never thought I'd have to explain this on Slashdot of all places.

      Let's see if this makes more sense:
      String tmp = null;
      if (tmp.length() > 0) /* <-- we blow up right here. */
      { //Do something.
      }

    11. Re:20 second explanation by AKAImBatman · · Score: 4, Insightful

      Consider the situation of apples. If you have an apple, then something is in your possession. If you don't have an apple, what do you have? Do you have some sort of object that depicts your lack of an apple? Obviously not. Yet in the world of computers, we have this special piece of data that shows our lack of data. It's a bit like getting a certificate that you have no apples. The certificate accomplishes nothing except to fill a space that does not need to be filled.

    12. Re:20 second explanation by morgan_greywolf · · Score: 1

      Sorry. I'm afraid I don't grok what a null reference is to begin with, which may be an issue.

      A pointer in C/C++ contains a memory address where some data or code start. For instance, there is really no string type in C. In C, a string is a pointer to the character where the string begins in memory. A value of 0 signals the end of the string.

      A null pointer in C/C++ (or just about any other language with pointers) is a pointer which points to nothing, hence, null.

      A null reference is what you get when you dereference a null pointer.

    13. Re:20 second explanation by AKAImBatman · · Score: 0

      My problem is that null references are typically used to signal the ends of lists or the place where the tree ends.

      From the perspective of comp-sci, is that a correct solution? The answer is "no". An absence of data should simply be an absence of data, not a piece of data that represents the absence of data.

      In other words, you need to imagine a language where the second reference is potentially non-existent. This is quite easy to represent in languages where maps are not closely related to 'null' values. Javascript comes to mind as an exmaple:

      var end = {};
      var start = {next: end};
       
      end.prev = start;
       
      if(!start.prev) alert("The reference 'prev' does not exist at the start of the list.");
      if(!end.next) alert("The reference 'next' does not exist at the end of the list.");
       
      alert("There are "+count(start)+" items in the list.");
       
      function count(list)
      {
        var count = 0;
       
        while(list)
        {
            count++;
       
            if(!list.next) return count;
            else list = list.next;
        }
      }

      That solution seems sort of ridiculously complex on non-OO languages, and a pain even for OO languages.

      This issue is caused by the structure of modern languages, nearly all of which assume that "null" is a valid value.

    14. Re:20 second explanation by Omnifarious · · Score: 1

      Oh, you have a special 'null instance' of any data type. That's just dumb. As someone else pointed out, it's just as easy to forget to check for it as it is to forget to check for null. And then your program ends up in some strange unpredictable behavior instead of generating a nice obvious segmentation fault when the reference is de-referenced.

    15. Re:20 second explanation by BigHungryJoe · · Score: 2, Interesting

      Ok, I'm far from an expert on SQL, but if NULL doesn't represent "unknown" in SQL, then why does

      select 1 from dual where 1 not in (2,3,NULL);

      return an empty set?

    16. Re:20 second explanation by Mr+Z · · Score: 1

      Ok, so you have a solution databases. Now describe how you would implement common data structures such as linked lists and binary trees. Keep in mind that in those contexts, NULL is just a sentinel value, so converting NULL to "a magic copy of the structure" isn't really eliminating NULL, since the contents of the structure are still meaningless.

      I imagine your solution ends up looking like Pascal's variant record, where you have a boolean tag that says "has next element" or "has child element", and a conditionally present field that holds that pointer. Hurray for wasting space.

      Decrying NULL pointers is very much like railing against sentinel values. NULL is just a sentinel value of "reference" or "pointer" type.

    17. Re:20 second explanation by ca111a · · Score: 1

      >denormalize
      I think that should be "normalize".

    18. Re:20 second explanation by AKAImBatman · · Score: 1

      Here you go: http://developers.slashdot.org/comments.pl?sid=1147437&cid=27052083

      The correct solution is absence of data is absence of data. Which means that even the reference should not exist.

    19. Re:20 second explanation by Anonymous Coward · · Score: 0

      Exceptional explanation! Mod parent up!

    20. Re:20 second explanation by AKAImBatman · · Score: 2, Informative

      That's a misunderstanding of the spec. NULL has no type, so evaluating NULL = 1 results in an unknown. That does not imply that NULL is an unknown value. I believe this reply on the PostgreSQL mailing list explained it best:

      0 <> NULL (Indeed nothing equals NULL, other then sometimes NULL itself)

      0 <> 1

      Therefore, the statement: 0 NOT IN (NULL, 1)
      Should always equate to false.

      Therefore No rows returned. Ever.

      It's a bit weird, but it makes sense when you actually follow the logic.

    21. Re:20 second explanation by AlecC · · Score: 2, Informative

      What NULL "means" is undefined. There are at least two possible meanings, and it is up to the database designer to define, for every column in which null is allowed. The two meanings obvious meanings are either "unknown" or "has not got". For a Date Of Birth column, it is obviously "unknown", because everybody has a DOB. But what does a null Date Of Death column mean? In a commercial context, it probably means that, so far as the database is concerned, the person is still alive. But in a historical database, it could mean that the DOD is really unknown, or that the person is alive. Likewise an Address3 line might interpret NULL as Address3 is "unknown" if Address1 is null and "has not got" if Address1 is non-null. Good database design will always specify this.

      --
      Consciousness is an illusion caused by an excess of self consciousness.
    22. Re:20 second explanation by GooberToo · · Score: 1

      No. NULL in SQL represents an absence of data.

      I disagree. An empty set (empty result) represents the absence of data. NULL represents undefined data. An empty set is well defined. Undefined data, usually represented as NULL, is well, undefined.

    23. Re:20 second explanation by dshadowwolf · · Score: 1

      Actually... that code shouldn't blow up. It should result in a string with zero length. At least in modern compilers it'll be seen as an implicit cast from a constant 'C-String' to a C++ class, which will instantiate the class and assign the value of the c-style string to it.

      But you are correct in the essence of the example. For the code to actually 'blow up' you'd want something more like:

      String *tmp = const_cast<String*>(null);
      if(tmp->length() > 0 ) /* this will blow up */
      { //Do something
      }

      And yes, this is just pedantry, but I believe in providing valid examples to help people understand what is happening.

    24. Re:20 second explanation by DaleGlass · · Score: 1

      Because anything a NULL interacts with becomes a NULL. 1 + NULL is NULL, and so on. Which then is ultimately evaluated as false in a WHERE.

      In your example, an argument could be made that you can't determine whether something exists in a list containing an undermined value.

      Suppose this example:

      Is there a fruit in this list of pictures?
      (car) (mouse) (fox) (literal hole in the paper where a picture should be)

      This question can't be answered, because you don't know what should be where the hole is.

    25. Re:20 second explanation by Mr+Z · · Score: 1

      Ok, in the Javascript case, you make the "next" or "prev" fields disappear, which isn't hard to do in such a dynamic language. It's the difference between "if (!exists($hash{$key})" and "if (!defined($hash{$key}))" in Perl. (ie. not a huge difference, but sometimes important.)

      It sounds pretty much identical to the variant record statement I made above, just with slightly different mechanisms of implementation. In the end, though, you need some way of signaling "the end" of something. We're arguing over how "in band" or "out of band" it should be.

    26. Re:20 second explanation by AlecC · · Score: 1

      Which is solved if lists and trees are implemented within the system in the same way as integers and floats. Lists are implemented in Python. The article was referring to language design: I think most language designers today would ensure that lists, both fixed and variable, were either in the language or easily implemented in efficient library functions. Trees don't seem to have the same near-universal acceptance.

      --
      Consciousness is an illusion caused by an excess of self consciousness.
    27. Re:20 second explanation by Anonymous Coward · · Score: 0

      which was his original point, I believe - NULL is represents "unknown" in SQL (the hole in your paper is the "unknown")

    28. Re:20 second explanation by Anonymous Coward · · Score: 0

      This issue is caused by the structure of modern languages, nearly all of which assume that "null" is a valid value.

      More like assuming that a variable has to exist before you can refer to it in code. Nearly all compiled languages would blow a gasket on your idea, since "next" has to exist for every instance of the object or none, and whatever it is it has in there to typecast to false for the ones where it's "empty" is null by another name.

      To not have a "next" pointer at all in the last item in these languages, you'd have to have a linkedlist class with two subclasses: car and caboose. Everyone deals with the linkedlist interface, from which car overrides next() to return the next object and caboose overrides next() to throw an exception (well, can't say we're solving it by returning null ;). (add an engine subclass for a doubly-linked list, a trolley subclass for a doubly-linked list of one item, and some kind of empty subclass for an empty list). This satisfies the compiler that none of the linkedlist objects have a next pointer and all of the car objects have a next pointer, while meeting your condition that the last object in the list not have a next pointer. Add in the extra work to convert between car/caboose as needed when the last object in the list changes. (Technically oo-breaking, since you'd have to modify the pointers of the last car before the caboose, and what happens to the pointer the caller is holding when you need to change the first car in the list to a caboose? Perhaps the "best" answer is to make linkedlist a class that contains cars and cabooses rather than a parent class of cars and cabooses, something like an iterator)

    29. Re:20 second explanation by Anonymous Coward · · Score: 0

      The prior example was perfectly valid Java. You can tell by "null" in lower case and "String" as a type name, where C++ would use "NULL" and "std::string".

    30. Re:20 second explanation by prgrmr · · Score: 1

      This issue is caused by the structure of modern languages, nearly all of which assume that "null" is a valid value

      I'll take a step further back in time and suggest that the problem lies with early computer OS's and programming languages that didn't reset memory after any given process was run, so the next process couldn't count on memory being in any particular state when it got to use it, hence the need for a token value to represent null.

      And perhaps this goes back to computer design, in that memory cannot be "empty" in the classic sense because a memory location can only be 1 or 0.

    31. Re:20 second explanation by Vellmont · · Score: 1


      Because anything a NULL interacts with becomes a NULL. 1 + NULL is NULL, and so on. Which then is ultimately evaluated as false in a WHERE.

      What I don't understand is why this is a legal expression. Why not simply return an error on trying to compile such a statement?

      --
      AccountKiller
    32. Re:20 second explanation by jadavis · · Score: 4, Insightful

      It's a bit weird, but it makes sense when you actually follow the logic.

      Not really.

      The expression "0 <> 1" is true, but the poster you referenced also says "0 <> NULL", which is NOT true, it is NULL.

      Additionally, NULL is not always treated as false-like. For instance, if you added the constraint "CHECK (0 NOT IN (NULL, 1))", that would always succeed, as though it was "CHECK(true)".

      And if you think "it makes sense", consider this: ... WHERE x > 0 OR x <= 0
      If x is NULL, that statement will evaluate to NULL, and then be treated as false-like, and the row will not be returned. However, there is no possible value of x such that the statement will be false.

      I'm not a big fan of NULL, but I think the most obvious sign that it's a problem is that so many people think they understand it, when they do not.

      --
      Social scientists are inspired by theories; scientists are humbled by facts.
    33. Re:20 second explanation by DragonWriter · · Score: 1

      Ok, I'm far from an expert on SQL, but if NULL doesn't represent "unknown" in SQL,

      "Unknown" is represented by NULL, but NULL does not (necessarily) represent "unknown". As GP says, NULL represents the absence of data (specifically, the absence of data regarding a value for an attribute within the domain defined for the attribute). Among the many meanings NULL can have:

      1) The datum exists, but it is unknown (or, equivalently, cannot be determined).
      2) The datum does not exist.
      3) The entity has the attribute in question, and its value is known, but it is not within the domain defined for the attribute

      NULL is a really ugly thing that exists largely for efficiency, and I suspect that many, many databases that use nullable columns do so as an ill-considered premature optimization.
      But which ever one of of those (or other) meanings apply, the result of any operation on NULL logically must again be a NULL; in SQL implementations, this generally means that calculations with NULL produce NULL and comparisons with NULL are always false, though there are, I think, some odd complications with this in some implementations.

    34. Re:20 second explanation by pi_rules · · Score: 2, Informative

      It'll blow up in C# and Java.

    35. Re:20 second explanation by Omnifarious · · Score: 1

      That's only sort of a solution. There are many data structures aside from lists and trees. Even if you always use lists when you wish to have a variable number of pointers, it's still not clear to me that you can do it. Trees, for example, have a left pointer and right pointer that have different meanings. So you would have to have two lists, one for all the 'left' pointers (there really only ever being 0 and 1) and one for all the 'right' pointers.

      I suppose that works. Then a list of pointers containing 0 elements becomes your 'null' pointer. You could make that work for statically typed languages with generics. And it could be made efficient by have special built-in types for lists with very small numbers of elements that stored their elements 'inline' so you wouldn't be needlessly introducing an extra level of indirection.

    36. Re:20 second explanation by geekoid · · Score: 1

      NULL is needed.

      You have just violated relational DB theory.
      Game over. Tell him what he leaves with Johnny:
      "He leaves with NULL the home game."

      You need to have NULL to represent missing data, anything else is actual data.
      NULL is not actually a value. it's a placeholder indicating the absence of data.

      There is nothing wrong with NULL in SQL. There are only people who can't intuitively understand 3VL.

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    37. Re:20 second explanation by AKAImBatman · · Score: 1

      More like assuming that a variable has to exist before you can refer to it in code.

      Indeed. However, I will argue that it's the acceptance of null that causes this problem. Even in class-based code. There's nothing to say that I can't define a class like this:

      class Link
      {
          Object next;
          Object prev;
      }

      And still be unable to deal with the non-existence of "next" or "prev". In fact, all we've done is assume that only "next" and "prev" are valid values. So "new Link().next = new Object()" would work while "new Link().myObject = new Object()" would fail. Thus "if(!mylink.prev)" can be perfectly valid syntax in a class-based language.

      However, that does leave one gap. We want to do as much type checking as possible. Ergo, we would probably want to introduce a "phantom" modifier. e.g.:

      class Link
      {
          phantom Object next;
          phantom Object prev;
          Object value;
       
          public Link(Object initialValue)
          {
              this.value = initialValue;
          }
      }

      The idea is that the compiler would throw an error if any of the following are true:

      1. An attempt to access a member is made prior to its initialization.
      2. A non-phantom reference is not initialized in the constructor.
      3. An attempt is made to delete the value of a non-phantom member.

      A runtime error would be thrown if the value of uninitialized phantom member is assigned to anything. e.g. These are errors:

      Link link = new Link(new Object());
       
      link.next = link.prev; //Error! prev is not initialized.
      link.value = link.next; //Error! next is not initialized.
       
      return link.next; //Error! next is not initialized.

      That last line would make getter methods slightly more dangerous, but that's a good thing from a comp-sci perspective. Having your getters blow up immediately would demonstrate an issue with the program as soon as possible. For many situations, the compiler can even do an analysis and detect the situation at compile time. Thus the ultimate goal of type checking is better achieved by eliminating null values.

      Of course, that gets into the argument of whether type checking actually produces more reliable software or not...

    38. Re:20 second explanation by Rary · · Score: 1

      Consider the situation of apples. If you have an apple, then something is in your possession. If you don't have an apple, what do you have? Do you have some sort of object that depicts your lack of an apple? Obviously not.

      The above does not, of course, apply to tea.

      --

      "You cannot simultaneously prevent and prepare for war." -- Albert Einstein

    39. Re:20 second explanation by geekoid · · Score: 1

      In SQL NULL means absence of data and it isn't a Type.
      It is not undefined, it does not mean undefined, thinking of it as undefined is completly wrong and shows your database theory is a tad rusty.

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    40. Re:20 second explanation by AlecC · · Score: 1

      I said not that it means anything in SQL. I agree that it means "absence of data". But a database designer must specify what "absence of data" means in the context of this table, just as a C programmer must know what "not pointing to anything" (aka a C NULL) means in his context. Does "absence of data" in the Date of Death column mean the person is alive, or that the database does not know his death date? A matter of design, not programming.

      --
      Consciousness is an illusion caused by an excess of self consciousness.
    41. Re:20 second explanation by geekoid · · Score: 2, Informative

      You can disagree all you like, but read the spec. NULL is absences of data. Undefined data is still data, just not defined, since NULL isn't a type, it can't be any type data. IT was specifically created to show absence of data.

      Look it up.

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    42. Re:20 second explanation by AKAImBatman · · Score: 3, Informative

      You need to have NULL to represent missing data, anything else is actual data.

      I don't think you understand the argument. Having the following is incorrect:

      ID|Name|State|Address|Address2
      5|Bob|MN|12 East St.|NULL

      THIS is correct:

      ID|Name|State
      5|Bob|MN
       
      ID|Parent|Address|Order
      22|5|12 East St.|1

      Note how there is no NULL value. In fact, NULL is antithetical to relational theory as all set values should have a value. Missing data should be normalized away.

      There are only people who can't intuitively understand 3VL.

      3 value logic has nothing to do with it. 3VL actually creates problems in this case. In fact, your very own snarky comment above is a perfect example of how things go wrong with 3VL:

      ID|Contestant|Prize
      2|AKAImBatman|NULL
       
      resultset = sql("select Prize from Contestants where Contestant = 'AKAImBatman');
       
      //Prints the stupid "NULL" answer
      while(resultset.next()) print("He leaves with " + resultset["prize"] + " the home game.");

      FAIL.

      Now look at this situation:

      ID|Contestant
      2|AKAImBatman
      3|geekoid
       
      Parent|Prize
      3|Remedial 6th Normal Form
       
      resultset = sql("select Prize from Prizes join Contestants on Contestants.ID = Prizes.Parent where Contestant = 'AKAImBatman'");
       
      //Correctly prints nothing
      while(resultset.next()) print("He leaves with " + resultset["prize"] + " the home game.");

    43. Re:20 second explanation by geekoid · · Score: 1

      Wow, that analogy show you really do not understand what NULLs are for, and why there is a difference between empty data and absence of data.

      What if I needed to know whether or not you were offered an Apple? or turned down an Apple? or had the Apple taken away? or you had consumed the Apple?

      Those are different things, but in your world you would make them the same.

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    44. Re:20 second explanation by CecilPL · · Score: 1

      No no no! You're confusing objects and pointers. You can have an apple (object) or you can have a piece of paper that says "the apple in the fruit basket next to the microwave" (pointer). Everything's hunky-dory, unless somebody goes and eats that apple without telling you. Now you have a pointer that points to an object that isn't there.

      Wait, that's not a null pointer, that's more like a hanging pointer. I guess a null pointer would be like a piece of paper saying "the apple at the end of the universe". (You can get those from the restaurant there. ;))

    45. Re:20 second explanation by dshadowwolf · · Score: 1

      Yeah... no implicit casting in those languages... And they also don't have the "a string is an array of type 'char' terminated by an explicit '0' (ASCII 'NUL') character.

      So... I admit that I forgot about those two. Guess I spend too much time with my head stuck in masses of C and C++ and not enough in other languages.

    46. Re:20 second explanation by Moridineas · · Score: 1

      Actually... that code shouldn't blow up. It should result in a string with zero length. At least in modern compilers it'll be seen as an implicit cast from a constant 'C-String' to a C++ class, which will instantiate the class and assign the value of the c-style string to it.

      Well, it's not exactly valid stl c++ as written..but..I think an exact stl translation would be:


      #include<iostream>
      #include<string>

      main()
      {
              std::string tmp = NULL;

              if(tmp.length() > 0) {
                      std::cout << "Length greater than 0" << std::endl;
              } else {
                      std::cout << "Length not greater than 0" << std::endl;
              }
      }

      Which produces (fwiw, g++ (GCC) 4.2.1 20070719 [FreeBSD])...


      terminate called after throwing an instance of 'std::logic_error'
          what(): basic_string::_S_construct NULL not valid
      Abort (core dumped)

      So I'd say, yeah, it does barf. Doesn't change that your example is a more direct example of null pointer reference.

    47. Re:20 second explanation by AKAImBatman · · Score: 1

      See, I interpreted his post as an evaluation rather than as truth statements. Though I certainly see your interpretation. I read it as:

      0 <> NULL = NULL
      1 <> 0 = true
      NULL && true = NULL
      NULL ~= false

      Which makes perfect sense. So I guess the above is really what I was going after. :-)

    48. Re:20 second explanation by Pervaricator+General · · Score: 1

      So what you're saying, is that my 3 year old is really trying to teach himself advanced programming?

    49. Re:20 second explanation by nacturation · · Score: 1

      I think this one further in the thread contains a better explanation:

      a NOT IN b is equivalent in the spec to NOT(a IN b). a IN b is equivalent
      to a =ANY b. a =ANY b returns true if a = x is true for any x in b. a =ANY
      b returns false if a = x is false for all x in b. Otherwise it returns
      unknown.

      0 = NULL returns unknown
      0 = 1 returns false
      So, 0 IN (NULL,1) returns unknown.

      NOT(unknown) is unknown.

      WHERE clauses only return rows for which the search condition is true, so
      a row is not returned.

      --
      Want to improve your Karma? Instead of "Post Anonymously", try the "Post Humously" option.
    50. Re:20 second explanation by swillden · · Score: 1

      OODBMSes (which are really fancy RDBMSes with many "pure" relational features that work around the traditional weaknesses of RDBMSes)

      Just a nit, but many OODBMSes are not RDBMSes at all, instead they're really network databases, which are essentially a generalization of the old hierarchical database structure which is still heavily used in the mainframe world.

      --
      Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    51. Re:20 second explanation by AKAImBatman · · Score: 1

      What if I needed to know whether or not you were offered an Apple?

      Do you have an apple in your possession? No. You have an offer for an apple in your possession. Which is different from a certificate saying you have no apple.

      or turned down an Apple?

      Simple. You have no apple. Period. End of story. If you wish to remember the decision as a piece of information, you must record it. Then you have a record of the decision to reject an apple. You still don't have an apple and the certificate saying you don't have an apple is just as useless.

      or you had consumed the Apple?

      Simple. You have no apple. Period. End of story. If you wish to remember the consumption as a piece of information, you must record it. Then you have a record of the decision to reject an apple. Or you can investigate your gastrointestinal tract for evidence of apple consumption. Either way, you still don't have an apple and the certificate saying you don't have an apple is just as useless.

      Those are different things, but in your world you would make them the same.

      Actually, you are equating non-equatable information to null. It's a bit like if I scribbled information about apples on my certificate telling me I don't have an apple. I still don't have an apple regardless of what you infer from its absence.

    52. Re:20 second explanation by Espressor · · Score: 1

      DB design is a pretty good analogy for the concept

      I have to take issue with you on this.

      So if Address2 is optional, you would want to split Address into its own table with a parent key pointing back to the user entry.

      Sure. That works for the database layer because you assume a query language that let you directly access the Address2 table/entity class.

      Not so much so in programming languages.

      In programs, the concept of navigation is fundamental. For instance you want to give the implementor of the User class the possiblity to navigate from User to the Address2 possibly held by User, but only in that direction, by looking at the corresponding field/attribute.

      You do not want to give access to all the possible instances of Address2. There isn't / should not be any "select * from Address2 where user_key = 'myUser.key'" (unless in SQL or OQL of course, again, that's at the DB access layer, not at the business object layer).

      You do not want to break practices of neat programming structures (be they in OO or in procedural languages) that are meant to prevent maintenance from becoming nightmarish and costly. Yes, you could program a Address(2)Accessor class of some sort (increasing the complexity of your program - are you going to do this for every entity/class?), make that one a singleton (urrghh) if a desperate attempt to keep control of your program, but that will only make things more difficult to deal with in the long, medium and short term.

      In summary, while I think you make interesting points, I'm just saying one has to be very careful when making DB analogies for programming languages. Maybe a car analogy though... ? :-)

    53. Re:20 second explanation by dshadowwolf · · Score: 1

      Odd... must be that I tend to actually use the 'cast' operators. And yeah... looks like 'char * NULL' - which would be a zero-length C-style string - causes problems in C++ (which really irks me).

      I'm guessing what happens is that the STL tries to guess something about the string and it doesn't like being handed a C-Style string of zero length. I didn't know this as I hadn't actually tried running the program, I just did a compile-check for correctness. (maybe -Wall would have reported something...)

    54. Re:20 second explanation by Thiez · · Score: 1

      Depends on your language. In Java, his example would blow up as he claims it should (by throwing a NullPointerException).

    55. Re:20 second explanation by mikael · · Score: 1

      I have a closed cardboard box with a large cat that may or may not be alive...

      --
      Vintage computer adverts: http://www.vintageadbrowser.com/computers-and-software-ads
    56. Re:20 second explanation by Anonymous Coward · · Score: 0

      you want the Null Object Pattern

    57. Re:20 second explanation by vux984 · · Score: 2, Informative

      Normalizing the database can create a situation where the NULL is unnecessary.

      Not reallly. Suppose I'm going to do a mail out to my customers... so I need a table of addresses

      select *
      from addresses inner join addressline2s on addresses.pkey = addressline2s.fkey

      And what happens? I'm now missing all the addresses that don't have a line 2. Well that's worthless.
      how about:

      select *
      from addresses left outer join addressline2s on addresses.pkey = addressline2s.fkey

      Yay, all my addresses. And I can cursor through them. ... except wait... I've got a bunch of nulls in the returned set. Even though my database doesn't contain any nulls, my simple query does...

      So what was the point of eliminating them from the database?

      Now in the real world, any amount of information might be missing, not just line 2. There are addresses without cities, without streets, Addresses in particular are difficult to model well. In fact the whole 'address line 1, line 2, line 3' thing is aready a cop-out because its too much effort to normalize addresses into separate fields. And when dealing with international addresses, it usually just simplest to give them a multiline text block and say, here, you fill it out the way you want...

      Russian addresses for example are supposed to be upside down. In Canada the postal code is supposed to be after the province, in Sweden its before the city (and there is no province...)... etc. So even if you've got the right fields, the order is wrong. You could spend a year just modeling street addresses.

    58. Re:20 second explanation by EastCoastSurfer · · Score: 1

      I agree. Of course there are always exceptions, but I always work hard to design out any NULLs in my databases. The only place I still use them regularly is when dealing with start and end dates. Even then dealing with the nulls is annoying because you have to always check the end date for null and make it something for the query to use in a between like so:

      select * from tblFoo where mydate is between startdate and isnull(enddate, getdate())

      Of course you can make getdate() some really far date in the future if you want instead of getdate().

    59. Re:20 second explanation by IntlHarvester · · Score: 1

      Probably because it would make simple report querying a PITA if you had to specifically handle every nullable column.

      --
      Business. Numbers. Money. People. Computer World.
    60. Re:20 second explanation by EastCoastSurfer · · Score: 1

      Actually many implementations do return an error or at least a warning when you try execute expressions with nulls.

    61. Re:20 second explanation by clone53421 · · Score: 2, Funny

      ...this: 'if(hashmap.exists("myvalue")'

      ...is the "correct" check anyway...

      Well, it'd be "correct" if it had the right number of parentheses, anyway! ;p

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    62. Re:20 second explanation by crowne · · Score: 1

      If you don't have any values in your collection, then you know that you don't have a value.

      Although if you don't have a collection, then you have a null collection ... back to square one.

      --
      RTFM is not a radio station.
    63. Re:20 second explanation by thePowerOfGrayskull · · Score: 3, Insightful

      And if you think "it makes sense", consider this: ... WHERE x > 0 OR x <= 0 If x is NULL, that statement will evaluate to NULL, and then be treated as false-like, and the row will not be returned. However, there is no possible value of x such that the statement will be false.

      If x is NULL, the statement evaluates to false. This isn't "false-like"; NULL is the state of not having a value. Comparing a non-value to /any/ value of or range of values is logically false: X is neither LTE 0 nor is it GT 0; a non-value has no relation to the value 0.

      While you can use it to derive a true/false value, NULL is not a (in the RDBMS context) value at all. Would you say in mathematics "empty set" makes no logical sense?

    64. Re:20 second explanation by clone53421 · · Score: 1

      a =ANY
      b returns false if a = x is false for all x in b. Otherwise it returns
      unknown.

      Shouldn't it otherwise return "true"? But yeah, I can see how that works out: you'd expect it to only return "true" if one of the comparisons was "true", but it instead returns "true" if one or more comparison wasn't false – and since one comparison was "unknown", and that isn't "false", it returns "true". Then you negate that, and NOT(true) is false, so NOT(0 in (NULL,1)) returns false.

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    65. Re:20 second explanation by clone53421 · · Score: 1

      Hmm... well, dates are unsigned values (since computers don't do the BC/AD thing internally). Since neither "NULL" nor "infinity" make sense as a valid date, the elegant solution is to use 0x00...0 (for whatever the size of the date value is), or "NULL", in the dateofdeath column to indicate "unknown past" and use 0xFF...F (which is the unsigned machine equivalent of infinity) to indicate "unknown future" (in other words, the largest representable date, which you could calculate if you knew how the computer internally stored them).

      Course... that's a bit too much trouble to actually bother with implementing. I'm lazy...

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    66. Re:20 second explanation by clone53421 · · Score: 1

      THIS is correct:

      (snip)

      Note how there is no NULL value. In fact, NULL is antithetical to relational theory as all set values should have a value. Missing data should be normalized away.

      Begging your pardon, but that gets rather absurd if you scale it up.

      Instead of the single, simple table:
        users[ID, first, middle*, last, dob*, address1, address2*, email*, home*, work*, cell*]
      (using *s to indicate which columns may contain null values), you'd need:

      users[ID, first, last]
      middles[userID,middle]
      dobs[userID,dob]
      addresses[ID,userID,address,order]
      emails[userID,email]
      phones[ID,userID,phone,type]

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    67. Re:20 second explanation by AlecC · · Score: 1

      Also, that is machine code, not SQL. SQL has an built-in date type, whose internal representation is opaque, with which it is capable of doing date arithmetic e.g. finding the number of days between two dates expressed, in human terms, as year/month/day. One of the points of using a proper database it to avoid having to re-invent all the permutations of date arithmetic.

      You could perfectly well allocate magic dates for special meanings; this would be regarded by most database professionals as the dirtiest of kludges.

      --
      Consciousness is an illusion caused by an excess of self consciousness.
    68. Re:20 second explanation by AKAImBatman · · Score: 1

      If there's no null value, there's no way to null out a collection short of:

      a) Not declaring it
      b) Deleting the reference altogether

      Deleting the reference would mean that there's nothing to track it by. Any attempt to use a deleted reference would throw an error. e.g. If I did "delete(link)" the link variable would cease to exist. This is the thought process behind the Javascript language, which is probably the closest language I can think of to the ideal solution for this problem. (Of course, it still inherited a 'null' value even if you shouldn't ever use it.)

    69. Re:20 second explanation by manifoldronin · · Score: 1

      Some pieces of programming would become slightly more difficult. For example, 'if(hashmap.get("myvalue") != null)' would not be a valid construct. You'd need to perform a check like this: 'if(hashmap.exists("myvalue")'

      Of course, the latter is the "correct" check anyway, so the theory goes that the software will be more robust and reliable.

      It seems that you have only sidestepped the question "what should hashmap.get("myvalue") return when it can't find anything?"

      That needs to be answered before we can abolish NULL.

      --
      Tyranny isn't the worst enemy of a democracy. Cynicism is.
    70. Re:20 second explanation by xenocide2 · · Score: 1

      That's a misunderstanding of the spec. NULL has no type, so evaluating NULL = 1 results in an unknown. That does not imply that NULL is an unknown value.

      So there's known knowns, known unknowns, and then there's NULL.

      --
      I Browse at +4 Flamebait

      Open Source Sysadmin

    71. Re:20 second explanation by AlXtreme · · Score: 1

      If x is NULL, the statement evaluates to false. This isn't "false-like"; NULL is the state of not having a value.

      Mod parent up. Unlike GP (which is at +5 insightful and _almost_ gets it right), parent truly understands the concept of NULL in RDBMS's.

      Pity I don't have modpoints atm.

      --
      This sig is intentionally left blank
    72. Re:20 second explanation by clone53421 · · Score: 1

      Actually, rethinking that, this way of looking at it seems the clearest... one just has to remember that in three-state logic, NULL || FALSE is NULL, NULL && FALSE is FALSE, NULL && TRUE is NULL, and NULL || TRUE is TRUE. Also, ~NULL is NULL.

      0 NOT IN (NULL, 1) (can be interpreted 2 ways, both of which yield the same result):

      NOT((0 == NULL) || (0 == 1))
      NOT(NULL || FALSE)
      NOT(NULL)
      NULL

      (0 <> NULL) && (0 <> 1)
      NULL && TRUE
      NULL

      0 NOT IN (NULL, 0):

      NOT((0 == NULL) || (0 == 0))
      NOT(NULL || TRUE)
      NOT(TRUE)
      FALSE

      (0 <> NULL) && (0 <> 0)
      NULL && FALSE
      FALSE

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    73. Re:20 second explanation by AKAImBatman · · Score: 1

      Begging your pardon, but that gets rather absurd if you scale it up.

      Yes it does. Which is why NULLs are almost a requirement for existing RDBMSes. Absolutely no one is going to make an effort to reach 6th normal form, regardless of what relational theory says. An artifact of theory vs. reality if you will. That does not make RDBMSes correct, only convenient.

      Many of today's OODBMSes attempt to smooth away these ugly warts caused by implementation issues. Their success is so-so, but they are catching on. I think the biggest hurdle to their adoption is that programmers confuse OODBMSes and O/R mappings. The two are only tangentially related at best. That and there is a rather significant investment in existing RDBMS technology.

    74. Re:20 second explanation by Fulcrum+of+Evil · · Score: 1

      Normalizing the database can create a situation where the NULL is unnecessary.

      Sure, but you'd have to do things like make an address table with a reference to a customer in order to model a customer with no address, whereas with null columns, you just stick an address id in a customer record and let it be null. The approach with nulls is cleaner, as you can then add addresses to lots of things without modifying the address table, and you also get to share address records, which can save some space (addresses would have to be immutable for this).

      --
      "We returned the General to El Salvador, or maybe Guatemala, it's difficult to tell from 10,000 feet"
    75. Re:20 second explanation by Slime-dogg · · Score: 1

      Ok, I'm far from an expert on SQL, but if NULL doesn't represent "unknown" in SQL, then why does

      select 1 from dual where 1 not in (2,3,NULL);

      return an empty set?

      It returns an empty set because NULL means 'nothing.' No data. 1 is not 2, 3, or nothing.

      If it were unknown, then the result of a check of 1 against (2,3, null) would be null - because the value of null is undetermined.

      --
      You need to restart your computer. Hold down the Power button for several seconds or press the Restart button.
    76. Re:20 second explanation by clone53421 · · Score: 1

      You could perfectly well allocate magic dates for special meanings; this would be regarded by most database professionals as the dirtiest of kludges.

      Ok, good point. The best way to do that, then, would be to use NULL to represent "unknown" and then use another bool is-dead field to indicate whether NULL means "unknown in the past" and "unknown in the future" (we can safely assume that they have a date of death, even if they haven't died yet... it's just unknown). No, I don't think you should use another table to normalize out the unknown dates. That's silly, IMHO.

      (In some cases, say a 60-byte text field that may contain NULL, it might make sense to use the extra int to avoid allocating 60 bytes when you only needed one byte to store NULL... but even then you're doing an extra database lookup to find out whether the value exists.)

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    77. Re:20 second explanation by clone53421 · · Score: 1

      whether NULL means "unknown in the past" or "unknown in the future"

      Boy, I sure missed that one...

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    78. Re:20 second explanation by Fulcrum+of+Evil · · Score: 1

      This question can't be answered, because you don't know what should be where the hole is.

      It certainly can - the answer is no. What you can't answer is what the paper looked like before the hole was cut.

      --
      "We returned the General to El Salvador, or maybe Guatemala, it's difficult to tell from 10,000 feet"
    79. Re:20 second explanation by Blakey+Rat · · Score: 1

      Now try to figure out whether NULL = NULL. (Hint: it depends on which DB engine you're using.)

    80. Re:20 second explanation by Fulcrum+of+Evil · · Score: 1

      not true - the cat is its own observer, so the cat waveform collapses before you open the box. If the cat is a metaphor for some subatomic particle, the game changes, but as it was explained to me, anything big enough to have its own gravity (however weak) breaks the required symmetry for the superposed wave function thingy. (IANAParticlePhysicist)

      --
      "We returned the General to El Salvador, or maybe Guatemala, it's difficult to tell from 10,000 feet"
    81. Re:20 second explanation by scot4875 · · Score: 1

      Your way:

      Keep track of only the information that exists. Fine, this is a valid approach. We normalize our data and extract out nulls. Great. Now our information is spread out across X number of tables/objects/stores/whatever, where X is the number of potentially "missing" pieces of information + 1. So to query the non-existence of an item, you have to query (at least) two tables.

      Other (perfectly reasonable way) to do things:

      Store non-repeating information as part of a single record. Now, you have all of your information in one place, and the query for non-existence is essentially free.

      Now, I'm not saying that one way is necessarily better, or one way is "correct." I just tend to find that when someone has the attitude that "it must be done this way, otherwise you're wrong", they typically aren't thinking through all cases or all the ramifications of their claim. That, or it's just typical zeal from someone who's been indoctrinated to believe everything is black and white.

      --Jeremy

      --
      Jesus was a liberal
    82. Re:20 second explanation by AKAImBatman · · Score: 1

      It seems that you have only sidestepped the question "what should hashmap.get("myvalue") return when it can't find anything?"

      An error. Or more to the point, it wouldn't return at all. The software would fail. The idea being that the programmer should be forced to do an exists() check prior to performing a get(). He can't rely on checking a null return value. Theoretically, this prevents him from making mistakes in his code where the null slips through into a critical section.

    83. Re:20 second explanation by clone53421 · · Score: 1

      No, you'd need to scratch out "the apple in the fruit basket next to the microwave" and write "there is no apple". You then have a null pointer to an apple.

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    84. Re:20 second explanation by DaleGlass · · Score: 1

      But that's not a correct answer in terms of the exercise, assuming the hole is accidental and not intended.

      Which is what I'm getting at. In the sentence "select 1 from dual where 1 not in (2,3,NULL)", saying there's no 1 in a list of (2,3,NULL) would be incorrect.

      Why? Because the NULL stands for "missing value" in this case, which indicates that *something* must be in this place, but for whatever reason the data isn't there. So we can't say with certainty that there's no 1 in that list.

      It's like I can't say that I never had a coworker called Bob, because I didn't know the names of everybody working in the company.

    85. Re:20 second explanation by AKAImBatman · · Score: 1

      I'm not saying there aren't real-world reasons why things are done the way they're done. In fact, I use many of them myself. And I'm especially not arguing that everyone should leave this thread determined to delete the existence of all nulls everywhere.

      I'm only continuing on the topic, which is an explanation of how computer science views nulls. Which is that it's a concept that shouldn't exist in languages; at least not in the way it does today. (For example, Javascript has the concept of an 'undefined' value which is similar to a null, except that it is truly non-existent. The only time you ever see it is when you attempt to manipulate values that don't exist. e.g. Paste "javascript:alert(window.qwerty)" into your URL bar. The result will be "undefined". You can test for undefined values without invoking undefined as a value itself, and write appropriate language to handle the situation.)

    86. Re:20 second explanation by The+End+Of+Days · · Score: 1

      Normalizing the database can create a situation where the NULL is unnecessary.

      Not reallly. Suppose I'm going to do a mail out to my customers... so I need a table of addresses

      select *
      from addresses inner join addressline2s on addresses.pkey = addressline2s.fkey

      And what happens? I'm now missing all the addresses that don't have a line 2. Well that's worthless.

      So you don't like the technique because you don't know the correct syntax for querying it? Out of all the possible objections, personal ignorance is probably the least likely to be a good argument.

    87. Re:20 second explanation by Estanislao+Mart�nez · · Score: 3, Informative

      Variant types (or, put more generally, algebraic data types) are indeed a general solution for this problem, that can be reused for countless others.

      The simplest example here is the way you define linked list types in a functional language like Haskell. In pseudo-code (yes, I know this might not be valid Haskell code):

      data List a = EmptyList | Node a (List a)

      This is a data type declaration that says that the type "List of a" is either the singleton EmptyList value, or a 'Node a' value, which contains (as struct fields, basically) an element of type a and a List of a. (In case it isn't clear, 'a' is a type parameter here; so a list of strings would be 'List String', a list of integers would be 'List Integer', and so on.)

      This works just as well to allow you to define generic nullable type constructors (which the standard Haskell library provides):

      data Maybe a = Nothing | Just a

      The type 'Maybe String' represents a value that might be either 'Nothing', or 'Just x' for some x of type String.

    88. Re:20 second explanation by Darinbob · · Score: 1

      Or you can just have a language that does not have pointers, only references. All references have to be initialized to existing objects. If they're changed, they have to also change to be a reference to an existing object.

      This is somewhat inconvenient for low level programming where people just want a thin veneer over raw memory (such as C with strcpy, pointer arithmetic, etc).

      Ie, Smalltalk is a good example. There is a null object, "nil", that is often used as a signature for end of lists or unused references. However "nil" is a full fledged object and responds to messages like anything else, and you don't crash things if you dereference it. Though you may end up in the debugger if you send it a message it doesn't understand. To really screw things up you need to do something like "nil become: 1"...

    89. Re:20 second explanation by Bake · · Score: 1

      No, "absence of data" in the Date of Death column simply means that we don't have it, whatever the reason may be - it simply doesn't matter as far as the database is concerned.

    90. Re:20 second explanation by Estanislao+Mart�nez · · Score: 2, Insightful

      See my post right above yours. Basically, one way of "abolishing null" is to replace it with more general variant type features that allow you to guarantee that nulls can only occur where your program declares they may. In that case, the answer to your question is simple: if your hash table's if of type Map, then the get operation's signature is something like this:

      nullable V get(K key)

      The idea behind this sort of solution is that the nulls problem isn't the existence of nulls, but rather, the fact that the language type system forces every type in your program to admit null in its domain. The solution is to distinguish between the type of a Foo and the type of "Foo or nothing."

    91. Re:20 second explanation by Darinbob · · Score: 1

      Instead of pointing to null, the next to the last list element would point to a value that had the type 'last list element' and no pointer inside it.

      You can do this last element without having a null reference or null pointer or special type, etc. Just use an explicit object as a "sentinel". This is the only way to do it in some languages, and you can still do this way in C/C++:
          while (obj->next != &end_of_list)

    92. Re:20 second explanation by rpresser · · Score: 1

      OK, hotshot, normalize away the nulls in an outer join then.

      resultset = sql("SELECT A.Name as Dad, A.TaxOwed, B.Name as Son FROM Parents as A LEFT JOIN Children as B ON B.Parent = A.Name")

      while(resultset.next())
          if resultset["Son"] is null
              print (resultset["Dad"] + " has no children but still owes tax")

    93. Re:20 second explanation by Hognoxious · · Score: 1

      And when dealing with international addresses, it usually just simplest to give them a multiline text block and say, here, you fill it out the way you want...

      If you consider each column to be a fact about the object defined by the key, the problem with that approach is that you don't know what fact each entry means. There is a fancy term for this, vbut I don't remeber it.

      So even if you've got the right fields, the order is wrong. You could spend a year just modeling street addresses.

      If you put the right thing in the right field, and always in the right field, and only in the right field (so help me God) you just need some kind of template per country, e.g for Belgium: boxnumber, street housenumber [newline] postcode city.

      You should be able to find them from the IPU, or deduce them by looking foor a company in the required country. Shouldn't take you a year, if you ignore all the Bongo-Bongo Land type places.

      --
      Confucius say, "Find worm in apple - bad. Find half a worm - worse."
    94. Re:20 second explanation by Fulcrum+of+Evil · · Score: 1

      Because the NULL stands for "missing value" in this case, which indicates that *something* must be in this place, but for whatever reason the data isn't there. So we can't say with certainty that there's no 1 in that list.

      Yes we can. There is no 1 in that list. The null doesn't stand for missing value, it means the value isn't there, just like if I had a customer record with a null addressId - no address on record.

      It's like I can't say that I never had a coworker called Bob, because I didn't know the names of everybody working in the company.

      But you wouldn't be saying that. You'd be saying that you don't have a coworker bob that you know of, and that'd be just fine.

      --
      "We returned the General to El Salvador, or maybe Guatemala, it's difficult to tell from 10,000 feet"
    95. Re:20 second explanation by vux984 · · Score: 1

      So you don't like the technique because you don't know the correct syntax for querying it?

      Do you typically read half a post and then reply to it? Because it makes you sound like a tool.

      If you'd made it to the very next line of my post, you'd see that I did a left outer join to solve the "problem".

      The trouble with outer joins, however, as I go on to explain, is that you end up with nulls in the query result.

      Given the whole point of normalizing addressline2 into its own table was so that we wouldn't have to deal with nulls in our database... clearly this is ineffectual, because we still have to deal with them in query results.

    96. Re:20 second explanation by Anonymous Coward · · Score: 0

      There are 3 things I dislike about your function.

      • It returns undefined for count(null) or count(undefined). Both of these are possible inputs. For instance, in your code, I could call count(end.next). You're using JavaScript; JavaScript allows both null and undefined (or 5, NaN, or 'hello', for that matter). You can't ignore them.
      • Redundant loop exit conditions. Your loop terminates on !list, but that will never occur because list = list.next won't execute if (!list.next).
      • You needlessly abort inside a loop. You should use the exit condition for the loop to stop the loop, not an inner abort condition. Inner abort conditions should be for truly abnormal abort conditions, not normal loop termination.

      My function (and some calls with various arguments, to put it through its paces) would look like this:

      var list = {next: {next: {next: {}}}};
      /*for some weird reason we've decided to make it doubly-linked...*/
      for (var item = list; item.next; item = item.next)
          item.next.prev = item;

      /*4, which is the number I created...*/
      alert("There are "+count(list)+" items in list.");

      /*2, also obviously correct...*/
      alert("There are "+count({next: {}})+" items in {next: {}}.");

      /*1, because there is one item...*/
      alert("There are "+count({})+" items in {}.");

      /*1, because there is one item, though not the correct type... I'm not verifying correct type*/
      alert("There are "+count('hello')+" items in 'hello'.");

      /*1, uninitialised JS references contain undefined... IOW, these are values of the wrong type, and I'm still not verifying type (making a judgement call here)...*/
      alert("There are "+count(NaN)+" items in NaN.");
      alert("There are "+count(true)+" items in true.");
      alert("There are "+count(null)+" items in null.");

      /*0, because undefined is an un-initialised reference: the list contains 0 items...*/
      alert("There are "+count(undefined)+" items in undefined.");

      function count(list) {
          if ((!list) && (list !== undefined)) return 1;

          var count = 0;

          while(list) {
              count++;
              list = list.next;
          }

          return count;
      }

      And yes, I'm fully aware that you'd probably burn my eyes out with a red-hot poker right now if you were able.

    97. Re:20 second explanation by AKAImBatman · · Score: 1

      And yes, I'm fully aware that you'd probably burn my eyes out with a red-hot poker right now if you were able.

      Why? A simply "whoosh" will do. In case it wasn't obvious, I was deliberately avoiding both nulls and undefineds to make a point. If one allows undefineds, your objections disappear with a simple change:

      while(list)
        {
            count++;
            list = list.next;
        }
       
        return count;

      To your second objection, I could have used a "while(true)" in the original code, but that just offends my sense of style. ;-)

    98. Re:20 second explanation by Moridineas · · Score: 1

      I'm not at all a C++ expert, or even particularly knowledgeable when it comes to STL, etc, so I don't really have a clue. Seems a weird outcome to me as well. I just often like to try compiling snippets of code people post on slashdot.

      That's how I learned that in:


      int i = 1;
      int j = ++i + ++i;

      j was not at all what I expected! :p

    99. Re:20 second explanation by vux984 · · Score: 2, Interesting

      If you put the right thing in the right field, and always in the right field, and only in the right field (so help me God) you just need some kind of template per country, e.g for Belgium: boxnumber, street housenumber [newline] postcode city.

      You should be able to find them from the IPU, or deduce them by looking foor a company in the required country. Shouldn't take you a year, if you ignore all the Bongo-Bongo Land type places.

      Even before you get to bongo-bongo land.

      For Canada your base template might be:

      Mr. Randy Jones
      Widget Manufacturing Inc.
      #101 21 Cordova Street East
      Vancouver, BC, V3H 1T3
      Canada

      But then in comes:

      Mrs. Irene Smith
      General Delivery
      Small Creek, MB, R0E 0K0
      Canada

      "General Delivery", isn't a street or a company; it means drop it off at the post office, they don't bother with mail boxes for each person here. People just come in and ask the postmaster for their mail.) Used to be very common in small rural towns, still a reality in out-of-the-way enough places.

      or another type of rural address like:

      Alice Smith
      Box 22F RR4
      Somewhere, SK, S0N 0A0
      Canada

      Where instead of the street address of the recipient you are identifying a lockbox on a rural route somewhere.

      Then you've got institutional addresses like:

      Dr. Jon Driver
      Office of the Vice President
      3100 Strand Hall
      Simon Fraser University
      8888 University Drive
      Burnaby, BC, V5A 1S6
      Canada

      which needs a bunch of space for all kinds of internal routing information.

      And we haven't gotten out of Canada yet.

      Its not so much that you can't keep adding fields and templates to accomodate these, its that every time you build a system and roll it out, users will shortly bump into an address that doesn't fit... and then they cram the information into the 'wrong fields'. And you might as well have just given them a few blank lines to fill.

      Its also a royal hassle because the address entry form in your application becomes increasingly complicated to use, and the order the system needs to know information, is usually opposite from the way people like giving it.

      Giving them multiple lines to just write what they need is simpler, and doesn't cause problems on the corner cases. I usually use a hybrid for systems used in Canada: a few generic 'address lines' and then city/province/postalcode fields. And I think even there we've run into a couple addresses that don't have cities. Although things have gotten better... the post office in their efforts to automate things have been arbitrarily assigning street addresses to things that don't really have them. (Simon Fraser University, didn't used to have a 'proper' street address, it was just "Simon Fraser University, Burnaby, BC". They added a street address "8888 University Drive" primarily to accomodate computer systems that kept choking on there not being a street address.

      But even today, you might send a message to:

      Dr. John Smith
      Faculty of Arts and Sciences
      University Hall
      Cambridge, MA, 02138
      USA

      with no street number.

    100. Re:20 second explanation by manifoldronin · · Score: 1

      It seems that you have only sidestepped the question "what should hashmap.get("myvalue") return when it can't find anything?"

      An error. Or more to the point, it wouldn't return at all. The software would fail. The idea being that the programmer should be forced to do an exists() check prior to performing a get(). He can't rely on checking a null return value. Theoretically, this prevents him from making mistakes in his code where the null slips through into a critical section.

      So I call get(), get null back, forget to check null, and my program blows up. Or I forget to call exists(), call get(), and my program blows up. How is one scenario better than the other?

      --
      Tyranny isn't the worst enemy of a democracy. Cynicism is.
    101. Re:20 second explanation by shutdown+-p+now · · Score: 1

      If x is NULL, the statement evaluates to false.

      I'm not sure what Postgres evaluates it to, but I am fairly certain that SQL spec requires it to evaluate to NULL. Specifically:

      x = NULL -- NULL
      x <> NULL -- NULL
      x > NULL -- NULL
      x < NULL -- NULL
      NOT(x = NULL) -- NULL

      And then in a boolean context that NULL is treated as FALSE. But originally it's not, as the very last expression demonstrates - if X = NULL would be false, than NOT(X = NULL) would be TRUE. But it isn't - it's NULL as well. The only meaning of NULL for which this behavior has any sense is "value unknown".

      Of course, SQL NULL is so inconsistent, it's hard to derive any truly coherent meaning out of it...

    102. Re:20 second explanation by shutdown+-p+now · · Score: 1

      how about:

      select *
      from addresses left outer join addressline2s on addresses.pkey = addressline2s.fkey

      Yay, all my addresses. And I can cursor through them. ... except wait... I've got a bunch of nulls in the returned set. Even though my database doesn't contain any nulls, my simple query does...

      The reason why SQL OUTER JOIN necessitates NULLs - which is broken by design, by the way - is because there are no table-valued fields in SQL (and no, the existence of such is not inconsistent with the relational model, and no, it does not violate 1NF - go read C.J.Date).

    103. Re:20 second explanation by AKAImBatman · · Score: 1

      In an attempt to collapse these threads a bit, here's the answer from another thread: http://slashdot.org/comments.pl?sid=1147437&cid=27056115

    104. Re:20 second explanation by Anonymous Coward · · Score: 0

      Well said.
      the inventor of relational theory C.A Date wrote a follow up book about the *theoretical* null and the practical, real-world use of null. In a nutshell: Don't use it. Use default values and boolean flags (to represent state) instead.
      Seems clunky? Better than the ad-hoc rules that DBMS vendors invent to get around the fact that *one* null value in a result set should give the entire result as null.

    105. Re:20 second explanation by Estanislao+Mart�nez · · Score: 1

      No, "absence of data" in the Date of Death column simply means that we don't have it, whatever the reason may be - it simply doesn't matter as far as the database is concerned.

      No, it matters enormously as far as the database is concerned. The meaning of data is part of the general data management problem that databases are supposed to address. If somebody somewhere concludes that a dead person is alive when they should have concluded that they are dead, but their death date is unknown, the database has probably failed, in one way or another.

      In this case, the problem can be either data that's not normalized properly, or abuse of NULL to mean different things in different contexts. With the first kind of solution, you might record deaths and their dates as a separate base relation. With the second type, you introduce a finer distinction than just value-vs.-NULL; you'd have to distinguish "value doesn't exist" from "value exists, but is not known."

      I really think that database systems ought to have union data types, like ML and Haskell do. Then you wouldn't have to overload NULL; you'd just use your own enumerated alternatives.

    106. Re:20 second explanation by Mr2001 · · Score: 1

      In C#, it'll blow up extra good because String has no method called "length()". ;)

      --
      Visual IRC: Fast. Powerful. Free.
    107. Re:20 second explanation by Hacksaw · · Score: 1

      It's a bit like getting a certificate that you have no apples. The certificate accomplishes nothing except to fill a space that does not need to be filled.

      Except that the space is never not filled. 0 is a valid address. The certificate means we haven't figure out how many apples you have yet.

      --

      All the technology in the world won't hide your lack of vision, talent, or understanding.

    108. Re:20 second explanation by Anonymous Coward · · Score: 0

      in some cases determining membership in a group (ie checking your 1:1 collection to see if you do or do not have a value) can be prohibitively costly as opposed to doing a quick lookup in your collection.

    109. Re:20 second explanation by iluvcapra · · Score: 1

      I believe the current SQL spec says that no two NULLs are supposed to be equal, but no two NULLs are supposed to be distinct, but the distinction (ha ha!) between "equality" and "indistinguishability" on many RDBMSs is not throughly worked out.

      --
      Don't blame me, I voted for Baltar.
    110. Re:20 second explanation by twostix · · Score: 1

      resultset = sql("select Prize from Contestants where Contestant = 'AKAImBatman');

      resultset = sql("select Prize from Contestants where Contestant = 'AKAImBatman' and Prize IS NOT NULL);

      Perfectly acceptable in the real world, not perfect but often superior to creating a new table with the associated baggage that that brings along. Though in this case you fail at the argument your making, as Contestant should be in its own table as well and the prize -> contestant table should be a lookup to both Prize and Contestant tables as who's to say a contestant can't win more than one prize?

      You made the same error that your chiding the OP for.

    111. Re:20 second explanation by NaugaHunter · · Score: 1

      Yeah, because adding 'AND Prize IS NOT NULL' is so much harder than having dozens of tables.

      --
      R: That voice. Where have I heard that voice before? B: In about 365 other episodes. But I don't know who it is either.
    112. Re:20 second explanation by PDAllen · · Score: 1

      Long ago, you've set up a table with a bunch of entries, and at some point you decide not to enter a datum into a field (because, perhaps, you don't at present know the correct datum). This has to be stored somehow; and NULL is the placeholder that is used (avoiding placeholders is access-expensive). For obvious good reasons, NULL should be distinguishable from 'real' data. No problems so far.

      Then a bit later SQL is standardised, and by this time your database has quite a lot of NULL entries floating around, so you want NULL comparison tools to exist in SQL. So they are created. And then lots of DBA types proceed to abuse them in production software, by doing stuff like 'this field is INT but we allow NULL to be a wildcard'.

    113. Re:20 second explanation by complete+loony · · Score: 1

      What really annoys me in some RDBMS implementations is that NULL = NULL is false. So if you have a variable that might be NULL and you want to find all the rows that match the variable you have to test for NULL values separately.

      --
      09F91102 no, 455FE104 nope, F190A1E8 uh-uh, 7A5F8A09 that's not it, C87294CE no. Ah! 452F6E403CDF10714E41DFAA257D313F.
    114. Re:20 second explanation by totally+bogus+dude · · Score: 1

      But you're just changing the question to be one that you can answer, which isn't really a valid solution. At least, one expects a database server to handle statements in a consistent manner, and not to change the question to one which suits it better.

      Suppose your boss asks you if a particular customer's address is 123 Fake St. You look up the customer information in the database and found their address is NULL. Your boss wants a yes or no answer. What do you say? Unless the parameters of the database state that a null record has particular meaning, you can't answer it either way. It's unlikely they live at 123 Fake St, but you can't say for certain they don't. Alternatively, it's likely they do if the boss got that address from somewhere else. But either way, you can't confirm it, and you can't deny it.

      If we go back to the original question regarding why "select 1 from dual where 1 not in (2,3,NULL)" returns nothing, it's important to understand that the database server is trying to answer this for the general case, rather than for the specific case where a null record has some kind of rational meaning. All it can really do is say either "the question is nonsensical" or "the question is impossible to answer given the available data".

      Suppose you're taking an exam and your copy of the questions has a photocopying error rendering some of the answers for a multiple choice question illegible. You can see option a) which is wrong, option b) which is also wrong, and then there's a black space where more options should be, and finally e) none of the above. What do you do? Assuming you actually care about the score you get for this exam, you're going to tell the instructor your test is unreadable; because there's a good chance that if you select the "right" option given what you can read, the automatic marking system will mark your answer as incorrect.

    115. Re:20 second explanation by fractoid · · Score: 1

      NULL = NULL should evaluate to NULL, not true or false.

      --
      Rampant carbon sequestration destroyed the Dinosaurs' tropical paradise. I'm here to help repair the damage.
    116. Re:20 second explanation by fractoid · · Score: 1

      If someone concludes that a dead person is alive, or vice versa, from the fact that no death date is recorded, then that person has failed, not the database. If the application through which the person interacts with the database interpreted that lack of a death date as the person being alive, then the application has failed or the data are faulty. If the database design doesn't say anything about the issue, then it's the database's fault.

      --
      Rampant carbon sequestration destroyed the Dinosaurs' tropical paradise. I'm here to help repair the damage.
    117. Re:20 second explanation by FlyingGuy · · Score: 1

      Nope...

      I have a score of zero (0) - I have a score of one (1) - I have not yet scored NULL

      select * from players where score is null - eg: I have not yet scored

      select * from players where score = 0 - I have scored and my score is zero (o)

      --
      Hey KID! Yeah you, get the fuck off my lawn!
    118. Re:20 second explanation by pi_rules · · Score: 1

      Yeah, yeah, yeah. :)

      I thought about mentioning that in my "It'll blow up in C# and Java" comment but didn't want to get too pedantic. I made the same mistake when I went to verify that I was right and the compiler caught the error. I'm still trying to shake some Java habits after 2 years of being in .NET.

    119. Re:20 second explanation by jadavis · · Score: 1

      WHERE x > 0 OR x <= 0

      "If x is NULL, the statement evaluates to false."

      No, it does not. Get rid of the WHERE, and try it in a CHECK constraint, and it will never fail.

      Your claim that the statement evaluates to false does not make any sense at all. Try the exact same thing with a NOT in front of it: if it were really FALSE, NOT FALSE would be TRUE. But it's still NULL, and then the WHERE clause treats it as FALSE-like.

      As consolation, your logic is at least as good as the logic of the people who implemented SQL NULL.

      --
      Social scientists are inspired by theories; scientists are humbled by facts.
    120. Re:20 second explanation by jadavis · · Score: 1

      He sure sounded like he understood SQL NULL, anyway. Did you consider testing his claims?

      See my reply to him for further information.

      Or, see the SQL standard 2008 "Part 2: Foundation" (SQL/Foundation) section 4.5.2:

      ...any comparison involving the null value or an Unknown truth value will return an Unknown result.

      And "NOT Unknown" is defined to be Unknown (see 6.34: General Rules: 2).

      These are clear contradictions to the idea that NULL is false, or that the original statement in question is false. NOT FALSE is clearly TRUE, which shows that the statement does not evaluate to FALSE, because if you put a NOT in front of it, it's still unknown.

      The fact that a variety of highly analytical people in this thread are getting this wrong (after NULL has been ubiquitous for ages) is strong evidence that SQL NULL is a disaster. Keep in mind that this is not in any way an insult to anyone in this thread: the fact that you have misconceptions about NULL is probably a good sign.

      --
      Social scientists are inspired by theories; scientists are humbled by facts.
    121. Re:20 second explanation by jadavis · · Score: 2, Interesting

      "try it in a CHECK constraint, and it will never fail"

      While I have the standard open, here's a reference to back up my claim above:

      A constraint is satisfied if and only if the applicable <search condition> included in its descriptor evaluates to True or Unknown.

          -- SQL 2008 Part 2: Foundation (SQL/Foundation) section 4.17.2

      And I also tried it in PostgreSQL, which generally has respect for the standard.

      So, a constraint does, indeed, treat NULL as TRUE-like.

      --
      Social scientists are inspired by theories; scientists are humbled by facts.
    122. Re:20 second explanation by Eskarel · · Score: 1

      Bad analogy.

      NULL doesn't exactly represent your lack of an apple, your lack of an apple is actually quite easy to explain. If you ask someone, "Do you have an apple?", and they don't have an apple, they just say no.

      What NULL is for is when someone asks you what kind of fruit you have and you don't have any fruit at all.

      The only feasible answers to "What kind of fruit do you have?" when you have no fruit are to either answer nothing at all, or to say "none". Not answering is a rather useless thing to do, and "none" is essentially NULL. NULL (in databases) metaphorically is a special way of saying I exist, but I have no fruit.

      Of course, this doesn't always apply to the non database concept. In a lot of older programming languages(C particularly), null(as opposed to NULL) is an unfinished bridge. You've started to build the bridge, but it doesn't actually go anywhere at all. So if you cross it you fall into the void and all sorts of bad things happen. What you really need(and a number of newer languages have this) is an actual NULL which represents a bridge to a brick wall. If you go racing across it, bad things still happen, but they happen in a sensible explicable way.

    123. Re:20 second explanation by Anonymous Coward · · Score: 0

      Wow. Epic fail. Do you understand how one-to-many relationships work? GP's tables & code work just fine. In fact, that's exactly how it should be implemented.

    124. Re:20 second explanation by Fulcrum+of+Evil · · Score: 1

      But you're just changing the question to be one that you can answer, which isn't really a valid solution.

      And you're reading way too much into the question. Null doesn't mean what you think.

      Suppose your boss asks you if a particular customer's address is 123 Fake St. You look up the customer information in the database and found their address is NULL. Your boss wants a yes or no answer. What do you say?

      "We don't have an address for that guy". Seriously, that's what null means. If your boss can't handle uncertainty, you need a new boss.

      All it can really do is say either "the question is nonsensical" or "the question is impossible to answer given the available data".

      But the question is perfectly sensible: "1 not in (2,3,NULL)" evaluates to false. Null isn't a placeholder, it's null.

      --
      "We returned the General to El Salvador, or maybe Guatemala, it's difficult to tell from 10,000 feet"
    125. Re:20 second explanation by totally+bogus+dude · · Score: 1

      The boss is a metaphor for the database engine which has to resolve the query. Of course it can't handle uncertainty. Also, exactly what a "null" means in a particular field in a particular table in a particular database is dependent upon that database's design, and what any people or applications who interact with it assume null means. It might be a flag that means "never ship anything to this customer because they're a douchebag".

      But the question is perfectly sensible: "1 not in (2,3,NULL)" evaluates to false. Null isn't a placeholder, it's null.

      Yes but the point is that "1 IN (2,3,NULL)" also evaluates to false. As you say null isn't a placeholder, and the analogies are an attempt to explain why and how if you ask the database engine "is 1 not contained in the set (2,3,null)" the answer is no, yet if you ask it is 1 contained in the set (2,3,null)", the answer is still no. One way to explain it is that null isn't a tangible thing or value, and cannot be meaningful compared with anything else.

    126. Re:20 second explanation by GooberToo · · Score: 1

      So you're saying an empty set is simultaneously NULL and empty? Since when is an empty set NULL? A select returning no rows does not return NULL. It returns empty.

    127. Re:20 second explanation by thePowerOfGrayskull · · Score: 1

      Interesting find - that seems to have been added in the 2008 standard? I was only able to get a hold of the 2006 spec, and there's no such section.

    128. Re:20 second explanation by Anonymous Coward · · Score: 0

      Would you say in mathematics "empty set" makes no logical sense?

      I'd say it if you gave me $20

    129. Re:20 second explanation by Anonymous Coward · · Score: 0

      Probably a troll but here's a morsel anyway.

      E.F. Codd would be spinning in his grave if he had one.

    130. Re:20 second explanation by jadavis · · Score: 1

      *shrug*

      I don't have the 2006 standard; I didn't even know they released anything that year. 2003 standard says:

      A table check constraint is satisfied if and only if the specified <search condition> is not False...

      in section 4.17.3.

      NULL is not the same as FALSE, so unless the standard itself uses multi-valued logic, I believe my claim still holds.

      And really, I didn't mean to jump into the details and start citing the standard. We could talk all day about the implications. My primary point is the following:

      A lot of intelligent, analytical people who have been around NULL for a long time still fail to really understand it*. How can these people -- who are driving the reports upon which business relies -- really have confidence that they are getting the correct answers when NULLs appear at every turn**? SQL NULL is an unmitigated disaster.

      In other languages, C/Java NULL, Ruby nil, Python None, etc., all have the nice property that they throw an error quickly. SQL seems to think it can make sense from nonsense, and that's bound to result in wrong answers.

      *: In no way at all do I think I'm smarter than the people in this thread who got NULL completely wrong, I just decided to dig at this particular issue for a while.

      **: NULLs appear even if your tables don't store any NULLs at all. For instance, in an outer join, or as the result of an aggregate (other than a couple exceptions) with no input tuples.

      --
      Social scientists are inspired by theories; scientists are humbled by facts.
    131. Re:20 second explanation by jlehtira · · Score: 1

      Consider saving a grid of numerical data in a text file, say, a map of air temperatures or some other meteorological data. Only that you don't have data in all points. What do you do? Write -99 instead, because it can never be that cold, right? (unfortunately some people do that). What's worse, ad-hoc data formats are usually not well defined, commented or anything.

      After thinking about this real hard once, I decided to write "NULL". Because everyone knows what it represents, because there's no possible way anyone could think that's a valid number, and because C++ I/O turned out to support it with no special pain or code to write ;).

      How about sparse matrices in memory? Right, if they are sparse enough you should be doing something else anyway. What if you only have one third of values missing in random locations?

      Essentially, I think that sometimes the NULL "certificate" is the best solution. Even in real languages there's the concepts of "empty" and "nothing", and that's for a reason - sometimes it's easier to say "my hand is empty" than to say "my hand contains zero items".

  3. There was a bigger mistake: by teknopurge · · Score: 2, Insightful

    Null-terminated strings. The bane of modern computing.

    1. Re:There was a bigger mistake: by RetroGeek · · Score: 3, Informative

      A null terminated String is a misnomer. It is actually an array of chars which uses a special character to signify its upper boundary. So that a second variable is not needed to hold the upper boundary. Zero was chosen by K&R.

      In some languages, a String is an object, and the object holds the upper boundary, so a terminator flag is not required.

      --

      - - - - - - - - - - -
      I am a programmer. I am paid to produce syntax not grammar. Deal with it.
    2. Re:There was a bigger mistake: by morgan_greywolf · · Score: 1

      Auto-generated code documentation. Causes programmer laziness resulting in things that should be documented often don't get documented.

    3. Re:There was a bigger mistake: by Rik+Sweeney · · Score: 5, Insightful

      Null-terminated strings. The bane of modern computing.

      Yeah! Let's abolish them, life would be much simplerasdjkaRGfl$!jaekrbFt6634i2u23Q0CCA;DMF ASDJFERR

    4. Re:There was a bigger mistake: by Anthony_Cargile · · Score: 1, Troll

      Null-terminated strings. The bane of modern computing.

      Maybe I'm feeding a troll, but what else would you terminate it with without using something the string may contain? Keep in mind that null-terminated strings were, err, "invented" around the time ASCII was really the only fully widespread character standard, and something was needed to mark the end of a string for detection by software.

      The mistakes you speak of are made by programmers that don't know how to securely utilize this in certain environments. Mainly in buffers, but recall the lkml thread about the license macro in kernel modules being abused with '\0'.

    5. Re:There was a bigger mistake: by Anonymous Coward · · Score: 0

      In some languages (C++'s std::string), a string is an object, and the end of the string is marked by a 0 character. How is it a misnomer to call this a null-terminated string? Even C's char*, though not an object is still conceptually a string, and its end is marked by a null. A null-terminated string.

    6. Re:There was a bigger mistake: by aspoon · · Score: 1

      I'm all for null-terminated strings, but just for the sake of giving a counter-example, look at Microsoft's implementation of BSTR. It basically starts the string with a string length, then the rest of the string. So technically speaking, you don't need the null since you already know where the string would end. (Correct me if I'm wrong... it's been quite a while since I last played with BSTR)

    7. Re:There was a bigger mistake: by Anonymous Coward · · Score: 4, Funny

      I agree.ï½ï½ï½ï½ï½ï½ï½cï½ï½A
      5ï½)ï½"ï½ï½ï½lï½3åï½ï½ï½SLï½4ï½54Vï½iï½ï½ï½D.O%N|ï½ï½ï½Tï½2nï½ì'iï½ï½ï½;ï½
                                                        ï½,ï½ï½(85ï½Iï½{ï½ï½ï½ï½)ï½Oï½Æ¼ï½%Cï½iwï½ï½ï½ï½ï½ï½I!,.ï½Õ'ï½ï½ï½ï½!ï½òfsQï½ï½zï½ï½Gï½ï½ï½aï½zï½-@ï½ yï½Ë+ï½ï½ï½Xï½ï½ï½ï½"ï½cï½âï½ï½ï½ï½ï½ï½ï½ï½ï½ï½dï½nbÕoeï½ï½ï½ï½lï½ï½ï½ï½ï½;hmï½ï½

    8. Re:There was a bigger mistake: by hobbit · · Score: 1

      A null terminated String is a misnomer.

      True. It should be "NUL-terminated string".

      But the use of the word "string" is correct:

      5. A series of similar or related acts, events, or items arranged or falling in or as if in a line. See synonyms at series.

      --
      "Wise men talk because they have something to say; fools, because they have to say something" - Plato
    9. Re:There was a bigger mistake: by Panaflex · · Score: 4, Informative

      Which comes from Pascal - which has always had the length at the beginning. Hence why pascal strings always had limits.

      --
      I said no... but I missed and it came out yes.
    10. Re:There was a bigger mistake: by Anonymous Coward · · Score: 2, Informative

      false*. in fact, you have to call c_str() to obtain a null terminated string.
      what happen inside is opaque, and most probably std::string constructed with a grain of salt are the pascal kind (a memory allocation and a separate character counter)

      *depending on your std implementor.

    11. Re:There was a bigger mistake: by Hal_Porter · · Score: 1

      Have you seen that picture "\0 RLY"? It's an O RLY owl with no eyes or beak, just feathers.

      Having truncated strings with zero bytes for various hacks, that really makes me laugh. Unfortunately Google image search doesn't let you search for "\0 RLY".

      --
      echo -e 'global _start\n _start:\n mov eax, 2\n int 80h\n jmp _start' > a.asm; nasm a.asm -f elf; ld a.o -o a;
    12. Re:There was a bigger mistake: by Chrisq · · Score: 1

      Which comes from Pascal - which has always had the length at the beginning. Hence why pascal strings always had limits.

      And originally from Cobol, where strings were fixed length (says he with 90% certainty)

    13. Re:There was a bigger mistake: by kLaNk · · Score: 1

      Minor nit for those not familiar with BSTRs: In a BSTR the length technically comes before the start of the string (pBSTR[0] actually points to the first character in the array).

      Technically having a BSTR be null terminated wouldn't be required if it wasn't for the fact that the whole purpose of a BSTR was to allow these strings to be passed around to existing functions which only expected simple null terminated WCHAR* strings).

    14. Re:There was a bigger mistake: by Bill,+Shooter+of+Bul · · Score: 1

      Oh they did have limits, but you could still break them. With turbo pascal 7 you could read a line of input from a file into a fix length string that went over the limit you had set for the string. Allowing you to write into areas of memory you weren't supposed to have access to.

      --
      Well.. maybe. Or Maybe not. But Definitely not sort of.
    15. Re:There was a bigger mistake: by cant_get_a_good_nick · · Score: 1

      PEDANT ALERT.

      NULL is a special pointer value, which is 0 in source code, but may or may not be 0 in object code. The compiler sets it to whatever the ABI defines the special flag pointer to be. The size would be whatever a pointer size is on your platform

      NUL byte, a single byte of 0x00 in both source and object code. In C-style strings, it's a marker that terminates the string.

      Not the same thing.

    16. Re:There was a bigger mistake: by Exitar · · Score: 1

      But since you use C to write more optimized code, using one byte for the terminator uses less space than using N bytes to memorize the actual string length, unless you're fine with strings with max length of 255.

    17. Re:There was a bigger mistake: by morgan_greywolf · · Score: 1

      Why presume that one would care? Not all languages are like C. In Python and Java, I believe that the way strings are represented is left up to the language implementation. The main rule in Python is that strings are immutable -- so the storage requirements are fixed and known at runtime.

    18. Re:There was a bigger mistake: by Anonymous Coward · · Score: 5, Funny

      Just allocate the same amount of memory for everythi

    19. Re:There was a bigger mistake: by Hal_Porter · · Score: 1

      Windows mostly uses counted (unicode) strings in kernel mode

      http://msdn.microsoft.com/en-us/library/aa380518(VS.85).aspx

      The idea is that you only interact with these strings by calling run time library runctions RtlXxx rather than fiddling around with pointers. It's actually quite OK once you learn how it works.

      Symbian is obsessed with string descriptors too, and it has far too many types of them. You also need to push them onto a clean up stack so they can be freed if your code "leaves", a sort of pseudo exception.

      Even simple string handling ends up incomprehensible gibberish.

      http://descriptors.blogspot.com/2005/05/20-how-do-i-use-heap-based-buffer.html

      E.g.

      _LIT(KFred, "Fred"); // Allocate a heap descriptor of max length 4
      HBufC* heapBuf = KFred().AllocLC();

      _LIT(KCyril, "Cyril");
      TPtr ptr(heapBuf->Des()); // Modifiable TPtr over heapBuf data area
      ptr = KCyril(); // This would panic because max length (4) is exceeded // Instead, we need to do a reallocation // Leave on cleanup stack in case the realloc fails and a leave occurs
      heapBuf = heapBuf->ReAllocL(5); // Realloc succeeded, but heapBuf pointer may have changed // We must update the pointer stored on the cleanup stack
      CleanupStack::Pop(); // Push it off // Push it back on again
      CleanupStack::PushL(heapBuf);

      Note this guy knows what he's doing, code from someone who doesn't is much worse than this. Good job he knows that he has to update the pointer on the cleanup stakc beacuse ReAllocL might have changed it.

      --
      echo -e 'global _start\n _start:\n mov eax, 2\n int 80h\n jmp _start' > a.asm; nasm a.asm -f elf; ld a.o -o a;
    20. Re:There was a bigger mistake: by nidarus · · Score: 1

      Maybe I'm feeding a troll, but what else would you terminate it with without using something the string may contain?

      How about Pascal-like strings, where you keep the length of the string in the first couple of bytes. It also has the advantage of making strlen O(1).

    21. Re:There was a bigger mistake: by dunkelfalke · · Score: 1

      but then again strlen() would be more than x times faster (x is the length of the string).

      --
      "It's such a fine line between stupid and clever" -- David St. Hubbins, Spinal Tap
    22. Re:There was a bigger mistake: by Anonymous Coward · · Score: 0

      NUL byte, a single byte of 0x00 in both source and object code.

      PEDANT FAIL.

      I don't know of any language that uses a NUL byte as the source representation of a NUL byte.

      In C, you might represent a NUL byte as 0 or '\z' or "\x00" depending on context (and that list isn't exhaustive). But never with a NUL byte.

      Indeed, NUL bytes in source are often ignored or cause the compiler to ignore the rest of the line. But neither behaviour is standard and depends on the particular compiler.

    23. Re:There was a bigger mistake: by Greyfox · · Score: 1
      If it was that much of a bane there's nothing that says we can't replace it. You could always write your own string library that handles all that transparently. Your strings might still be null terminated so that you can just pass the character pointer to the old C string routines if you need to, but you never need to touch the data directly if you don't want to.

      As a side note C++ attempts to do this with "string" but a lot of C++ code I've looked at still uses old-school null terminated character pointers.

      --

      I'm trying to teach myself to set people on fire with my mind... Is it hot in here?

    24. Re:There was a bigger mistake: by samweber · · Score: 1

      But since you use C to write more optimized code, using one byte for the terminator uses less space than using N bytes to memorize the actual string length, unless you're fine with strings with max length of 255.

      In almost all cases, that's a false economy. Okay, in the worst case you use one word instead of one byte for the string. In lots of cases, though, the fact that you want memory regions to be word-aligned means that you will end up allocating the N-1 bytes anyway.

      And, in return:
        * String equality will take only 2 memory reads if the strings are two different lengths
        * String concatenations take O(n_2) time, where n_2 is the length of the second string, instead of O(n_1+n_2).
        * Getting the string length is a constant time operation.
        * Operations that need to check for buffer overflow can do a single cheap check at the beginning of the operation.
        * You don't have the development, debugging and support costs associated with the all-too-common off-by-one and overflow bugs.

    25. Re:There was a bigger mistake: by nidarus · · Score: 1

      A null terminated String is a misnomer. It is actually an array of chars which uses a special character to signify its upper boundary. So that a second variable is not needed to hold the upper boundary. Zero was chosen by K&R.

      OK... But, if you don't mind me asking, so what?

      All modern C implementations use null terminated strings, for which the term "null-terminated" is in fact, very accurate, and they are, as teknopurge stated, a big problem (I wouldn't say "the bane of modern computing" though - C# and Java certainly don't have those).

      You're right, it didn't have to be NULL, and it is technically an array (actually, it's technically a pointer - C doesn't have real arrays), but really, was there some point, aside from misguided pedantry, that I missed?

    26. Re:There was a bigger mistake: by fl1ckmasterflex · · Score: 1

      Storing / creating the string would be slower. You would have to count the tokens in the string before you could store it.

    27. Re:There was a bigger mistake: by Dog-Cow · · Score: 1

      And in Object Pascal, all strings are null-terminated along with having Pascal-like attributes.

      Such qualities are not mutually-exclusive.

    28. Re:There was a bigger mistake: by 5pp000 · · Score: 1

      Agreed. Not distinguishing pointer types that can be null from those that can't was only a billion-dollar mistake. Using null-terminated strings in C and Unix was closer to a trillion-dollar mistake. Almost the entire security industry exists because of it.

      I love to blame Microsoft for poor security as much as the next /.er, but as long as we're pointing fingers, some of them should be pointed at Kernighan and Ritchie, for creating and propagating a language in which programs were insecure by default.

      I know, I know, K&R are gods, not mere mortals. Well, guess what, maybe they're mortal after all, and they screwed up big time on this one.

      --
      Your god may be dead, but mine aren't!
    29. Re:There was a bigger mistake: by pdbaby · · Score: 1

      16It really would!

      --
      Global symbol "$deity" requires explicit package name at line 2. - If only $scripture started "use strict;"
    30. Re:There was a bigger mistake: by blueg3 · · Score: 1

      If C doesn't have real arrays, what, then, is a real array?

    31. Re:There was a bigger mistake: by Anonymous Coward · · Score: 0

      Are you one of those morons who thinks its OK to dump anything vaguely technical in a technical discussion.

      Need a little pat on the head? Yes.. Yes.. you're a good developer too. Clap Clap.

      I do OS level system libraries and even without knowing a damn thing about symbian I can tell that this is BASIC stuff and yet you seem to be fascinated by it...

    32. Re:There was a bigger mistake: by Culture20 · · Score: 1

      Twitter already made that mistake, and see how much their servers crash?

    33. Re:There was a bigger mistake: by dunkelfalke · · Score: 1

      now, which happens more often, strlen or creating a string?
      then again, even that problem is already solved in pascal - you can specify the size of the string when defining it.

      --
      "It's such a fine line between stupid and clever" -- David St. Hubbins, Spinal Tap
    34. Re:There was a bigger mistake: by Anonymous Coward · · Score: 0

      255 characters should be enough for anyone.

    35. Re:There was a bigger mistake: by rthille · · Score: 1

      Terminate them with ',' (comma):
      http://cr.yp.to/proto/netstrings.txt

      --
      Awesome furniture, accessories and cabinetry in Santa Rosa, CA: http://humanity-home.com/
    36. Re:There was a bigger mistake: by geekoid · · Score: 1

      Ironically Pascal's wife never had limits~

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    37. Re:There was a bigger mistake: by Mr+Z · · Score: 1

      Traditional Pascal had fixed length strings, and the maximum length of the string was part of the type. That is, there wasn't a "string" type, but rather arrays of characters. "Array [1..80] of character" is a different type from "Array [1..100] of character". To have "variable length" strings, you needed to package these up into a record type, with the length as a separate field.

      The early Microsoft BASICs stored the string length in the byte before the string, as I recall, and I believe Turbo Pascal added a variable length String type, but that came later.

    38. Re:There was a bigger mistake: by EvilNTUser · · Score: 1

      Those aren't the only possible operations. Let's say you want to split a string into words (command line arguments maybe?). "apple pear orange lemon"

      I'm not a C expert, but as far as I've understood, you would just create pointers to a, p, o, and l, and replace " " with null. If the memory is on the heap, you would remove them all using the pointer to a.

      If the length was stored in the string, you would have to allocate new memory to fit the >1 byte integers.

      --
      My Sig: SEGV
    39. Re:There was a bigger mistake: by Anonymous Coward · · Score: 0

      alternative?

    40. Re:There was a bigger mistake: by Trepidity · · Score: 1

      Also, strcmp() is much faster for strings that have non-equal length but long common prefixes, and strcat() onto a long string is much faster since you can jump right to the place to begin appending at.

    41. Re:There was a bigger mistake: by Trepidity · · Score: 1

      Ok, minor nit in my own post, I suppose strcmp() as C defines it actually wouldn't be faster, since you'd still have to scan through to decide whether to return +1 or -1 for non-equal strings. A function that only looks for string equality/nonequality is considerably faster with many Pascal-style strings, though.

    42. Re:There was a bigger mistake: by teknopurge · · Score: 1

      Not a troll. C and ASM devs know what my comment meant. It's not the strings themselves that are the problem, it's the bounds checking, or lack thereof by many OS's over the years.

      Stack Smashing/Buffer Overflows FTW.

    43. Re:There was a bigger mistake: by Anonymous Coward · · Score: 0

      "It is actually an array of chars which uses a [null] to [terminate it]."

      Yes. Hence, null terminated.

    44. Re:There was a bigger mistake: by Anonymous Coward · · Score: 0

      That idea is great! you deserve a raise!!!!!

      salary: 80,000
      new salary: 82

      Thanks for all your hard work this year.

      Sincerely,
      The Management

    45. Re:There was a bigger mistake: by cant_get_a_good_nick · · Score: 1

      true (somewhat)
      sorry for my lack of clarity.
      a NUL in source code isn't a character NUL, but however you chose to represent it, e.g \0, 0x00. This follows the normal translation to object code in compilation.

      A NULL is special. A NULL is 0 in the source, but in translation to object code, the compiler sees it as a 0 in pointer context (either implicitly or a cast) and converts it to whatever's appropriate. This may be a pointer sized with all zeros, it may be not. The specialness is that the language doesn't define it, the ABI does.

    46. Re:There was a bigger mistake: by gbutler69 · · Score: 1

      And why they were limited to 255 chars.

      --
      Over-the-top Response Guy! Giving "Over-the-Top Responses" since 1970.
    47. Re:There was a bigger mistake: by scot4875 · · Score: 1

      If you're doing it right, you are counting the tokens in the string before storing it anyway.

      But eh, buffer overruns are no big deal, right?

      --Jeremy

      --
      Jesus was a liberal
    48. Re:There was a bigger mistake: by LordKronos · · Score: 1

      Actually, IIRC that is only true of the AnsiString type. I'm pretty sure that if you declare a ShortString (which was simply called a String in Delphi 1, and had to be explicitly declared as a ShortString in Delphi 2 and up) there is no terminating character.

      However, I'm not sure that anyone has actually bothered to use a ShortString in years (and for all I know, it may not even be in the language anymore), so I'm just nitpicking.

    49. Re:There was a bigger mistake: by Guy+Harris · · Score: 1

      All modern C implementations use null terminated strings,

      All implementations of C use or used null-terminated strings, as that's part of the language; it's not a characteristic of the implementation.

      (actually, it's technically a pointer - C doesn't have real arrays)

      Yes, it does have real arrays. In expressions, "array-valued" expressions are converted to "pointer-valued" expressions that point to the first element of the array (ANSI X3.159-1989, section 3.2.2.1 "Lvalues and Function Designators", 3rd paragraph).

    50. Re:There was a bigger mistake: by LordKronos · · Score: 1

      No need to count. Anytime you are assigning to a string, you know exactly what you are assigning. If you are assigning a constant, the compiler can count the characters. If you are assigning another string, you just copy its length counter. If you are appending, you just add one string's counter to the other's counter. If you are reading into the string as a buffer, then the read function is going to tell you the exact number of characters it read in. Even if you are copying from another string that is terminated and thus has no counter, all you have to do is copy until you get to the terminator (which you have to do anyway), then subtract the address/offset of the terminator from the start address/offset.

      Yes, it is still a tiny bit of extra work (an assignment, and possibly an addition and/or subtraction), but that's negligible for almost 100% of things.

    51. Re:There was a bigger mistake: by Anonymous Coward · · Score: 0

      true (somewhat)

      What did I write that isn't true?

      When I wrote "In C, you might represent a NUL byte as 0" I was referring to the usage:

      static char c = 0;

      at file scope which (typically) places a NUL byte in the static data section of the object file.

      I wasn't confusing NUL bytes with NULL pointers.

    52. Re:There was a bigger mistake: by Anthony_Cargile · · Score: 0, Troll

      I've written plenty of assembly for a variety of processor architectures, and almost all OS's I've dealt with at the assembly level, including my own, have used 0/NULL as the string terminator (higher-level languages just "hide" this). I've also seen and debugged many overflow problems, but much of this has become a thing of the past due to GCC and other compilers having built in stack smashing/overflow protection, implemented by IBM's ProPolice in GCC.

      I know fully what your comment meant, and yes - the way the strings are terminated/accounted for length-wise vary from implementation (e.g. Pascal vs. C), but the bounds checking is where most either don't enforce enough, or leave plenty of room for the programmer to "shoot themselves in the foot", as Bjarne Stroustrup said.

      And while I like the idea of immutable strings in some languages, sometimes it tends to get in the way of solving some problems, at least from a lower-level perspective. That, or I'm just way too set in my ways with C and other unchecked languages but who cares, as long as I check my bounds which seems to be a huge problem for many these days.

    53. Re:There was a bigger mistake: by cachimaster · · Score: 0

      The real problems are buffers overflows caused by the insecure C string librarAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA PWNED! DISREGARD THAT LOL

    54. Re:There was a bigger mistake: by pingveno · · Score: 1

      You don't need to use a character to terminate it. Just carry around the length of the string.
      typedef struct {
      int length;
      char *str;
      } string;
      D basically does this, except the length is part of the array itself.

      --
      "it's not about aptitude, it's the way you're viewed" - Galinda
    55. Re:There was a bigger mistake: by nidarus · · Score: 1

      Something that's not just syntax sugar for pointer arithmetic.

      I'm not even talking about bounds checking or anything fancy like that. I'm talking about stuff like 1[array] being synonymous with array[1], because 1+array == array + 1.

    56. Re:There was a bigger mistake: by nidarus · · Score: 1

      All implementations of C use or used null-terminated strings, as that's part of the language; it's not a characteristic of the implementation.

      I only said "modern C implementation" to give RetroGeek some slack - maybe he knows some obscure early implementation that uses 7 instead of 0 to terminate strings? Then he might have had some point.

      Yes, it does have real arrays. In expressions, "array-valued" expressions are converted to "pointer-valued" expressions that point to the first element of the array

      So, basically, it only has arrays in the sense the standard calls them "arrays", even though it also admits that they're actually pointers. Great.

      Obviously, C has arrays. And it also has null-terminated strings. But RetroGeek said that C's null-terminated strings are actually not "strings" because they're array of chars, and they aren't "null-terminated" because they could have chosen any character instead of NULL, and in that sense, C's arrays aren't "real arrays" either.

    57. Re:There was a bigger mistake: by giuda · · Score: 1

      Candlejack?

    58. Re:There was a bigger mistake: by blueg3 · · Score: 1

      Interesting. I was not aware that [] was how you did addition in C.

    59. Re:There was a bigger mistake: by Guy+Harris · · Score: 1

      So, basically, it only has arrays in the sense the standard calls them "arrays", even though it also admits that they're actually pointers.

      No. It has arrays in the sense that

      1. if you declare int foo[3];, the memory allocated for that is 3 ints and no int *'s;
      2. you can declare a pointer of type "pointer to {type}[N]", and, for example, have a function whose argument is "pointer to int[3]", and, if you pass that function a "pointer to int", or "pointer to int[2]", that will be a type mismatch (yes, I've actually used that feature, to make sure a function wasn't passed an undersized array).

      It doesn't have arrays in the sense that you can assign arrays or pass them, rather than pointers to them, or pointers to non-array elements of them, to functions, or return them from functions.

      So, no, they're not "actually pointers"; they're more like structures were in the old days of C, before you could assign structures, pass them as arguments, or return them from functions.

    60. Re:There was a bigger mistake: by nidarus · · Score: 1

      Pointer addition, yes.

      array[index] is just syntax sugar for *(array + index). And since array + index == index + array, index[array] works just like array[index].

    61. Re:There was a bigger mistake: by nidarus · · Score: 1

      First of all, you have a point, at least in #2 (to #1 one could say "so when you declare an array variable it's equivalent to pointer+malloc" etc etc).

      But you also agree that:

      It doesn't have arrays in the sense that you can assign arrays or pass them, rather than pointers to them, or pointers to non-array elements of them, to functions, or return them from functions.

      That is, in some pedantic sense, it doesn't have "real arrays", and that's basically my point (actually my point was the RetroGeek's post was pointless pedantry, but you get what I mean).

    62. Re:There was a bigger mistake: by againjj · · Score: 1

      As do NUL (not NULL) terminated strings. They have a limit defined by addressable memory. So, you want longer strings with a length at the beginning? Make your strings have a 32 (or 64) bit integer at the beginning instead of 8 bit like Pascal. Four bytes are cheap nowadays, and the reduction in problems would be worth it.

    63. Re:There was a bigger mistake: by againjj · · Score: 1

      Memory is cheap. Fixing bugs do to bad NUL termination is not.

    64. Re:There was a bigger mistake: by Exitar · · Score: 1

      Memory wasn't neither cheap nor abundant when C was created.

  4. Null is just a value by bytesex · · Score: 1

    Yeah, but wouldn't the first thing you'd do in the system API design of any non-null language be, the creation of a singleton object instance of the superclass of all objects, named 'null' ?

    Also, apart from 'null' there are loads of parameters than can have illegal ranges and must be checked to be proper.

    Thirdly, a similar rant can be had against non-range checking of enums in C (but then warning against it in switches (WTF?)).

    --
    Religion is what happens when nature strikes and groupthink goes wrong.
    1. Re:Null is just a value by Sneftel · · Score: 2, Insightful

      Actually, if you were defining a "null" value, you'd make it a Top-type, meaning it would be a subclass of all other types. Otherwise you couldn't set an arbitrary reference to point to null, because null would be insufficiently derived.

      --
      The opinions stated herein do not necessarily represent those of anybody at all. Deal with it.
    2. Re:Null is just a value by Garse+Janacek · · Score: 1

      Yeah, but wouldn't the first thing you'd do in the system API design of any non-null language be, the creation of a singleton object instance of the superclass of all objects, named 'null' ?

      No. That doesn't really make sense even in a lot of OO languages, anyway -- if my class Foo extends Object, and my function expects a Foo, then in a strongly-typed language you can't pass me an Object.

      In languages where this would be possible, it would nonetheless be very evil to start with a language that is designed to guarantee the presence of a valid reference wherever one is expected, and then impose conventions that require runtime type checking substituted for null-checking every time we access any value.

      Also, apart from 'null' there are loads of parameters than can have illegal ranges and must be checked to be proper.

      Of course the claim isn't that removing null would avoid the need for all range checking, or eliminate all resulting errors. But I think a pretty good case can be made that null pointer/reference errors have historically been the majority of such errors -- and if not, certainly the plurality. Same answer for your C enum example -- they may be terrible and may cause a lot of errors, but I think null caused even more...

      --

      I am the man with no sig!

    3. Re:Null is just a value by Anonymous Coward · · Score: 0

      If that was the first thing you did, the second thing you'd do is wonder why your code doesn't compile. eg in Java

      Object nul = new Object(); // doesnt work, object is abstract, and even if it wasn't...
      Integer foo = nul; // ... won't even compile due to the type mismatch

      It would work in weakly-typed languages, but that would miss his point entirely (he was talking about static type checking)

    4. Re:Null is just a value by Anonymous Coward · · Score: 0

      If that was the first thing you did, the second thing you'd do is wonder why your code doesn't compile. eg in Java

      Object nul = new Object(); // doesnt work, object is abstract, and even if it wasn't...
      Integer foo = nul; // ... won't even compile due to the type mismatch

      It would work in weakly-typed languages, but that would miss his point entirely (he was talking about static type checking)

      Just a fix... in Java...
      Object nul = new Object(); // does work, Object is not abstract

      Integer foo = nul; // ... won't even compile due to the type mismatch, but it easy to fix by casting:

      Integer foo = (Integer) nul;

    5. Re:Null is just a value by Estanislao+Mart�nez · · Score: 1

      Yeah, but wouldn't the first thing you'd do in the system API design of any non-null language be, the creation of a singleton object instance of the superclass of all objects, named 'null' ?

      If nulls truly are valuable in some cases, then the correct thing to do is to give the language optional nullable types. A variable of type 'Foo' is guaranteed to refer to some Foo, while a variable of type 'nullable Foo' might have null as its value. The compiler would then reject programs that tried to use variables or expressions of type nullable Foo in contexts that expected a Foo, which would force the programmer to write code to handle the null case in order to convert nullable Foo to Foo.

      The best examples we have of languages with no nulls is the ML/Haskell family, and they get away without having nulls by having labeled union types, which is a more general version of this idea. For every type t, in Haskell there is a type Maybe t, whose values are either something of type t, or a sentinel that stands in for "nothing."

      Also, apart from 'null' there are loads of parameters than can have illegal ranges and must be checked to be proper.

      And typeful programming can help you guarantee that your program is free from such errors, in many cases. Basically, construct a restricted type that encapsulates another, more primitive one, and have the constructors for the restricted type do the range checking. Then you have a compilation-time guarantee that all objects of the restricted type fall within the range you want.

  5. Wouldn't help by corporate+zombie · · Score: 5, Insightful

    Fine. No null references. So I create the same thing by having a reference to some unique structure (probably named Null) and I still *fail to check for it*.

    Null references don't kill programs. Programmers do.

        -CZ

    1. Re:Wouldn't help by Tridus · · Score: 1

      When the same mistake is repeated over, and over, and over, and over, and over again for decades, it's only natural to wonder if maybe letting it happen was itself a mistake.

      I mean, if I design a road and one car crashes, it's probably the driver. If there's crashes every day for 15 years? Either every driver is bad, or something is wrong with the road design.

      --
      -- "So they told me that using the download page to download something was not something they anticipated." - Bill Gates
    2. Re:Wouldn't help by Anonymous Coward · · Score: 0

      The difference is that you keep going instead of crashing. For example, iterating over a linked-list and failing to check for the Null sentinel will give you Node1, Node2, Node3, Null, Null, Null, Null, ...

      So it's turning a segmentation fault into an infinite loop, hereby saving BILLIONS of dollars! ...maybe.

    3. Re:Wouldn't help by nuttycom · · Score: 4, Interesting

      If you use a sane class for references that could possibly be null (like Option (aka Maybe in haskell) then your compiler will *force* you to handle the null case.

      This is where null went wrong, at least in statically typed languages: it's a hole in the type system that errors fall through into your program. When coding in Java, I make an explicit point to never return null from a method; if I have a situation where no reasonable return value might exist, I use the Option class from functionaljava.org and thus force the client to handle the possibility of the method not returning sensible data. Since Option obeys the monad laws, it's easy to chain together multiple things that might fail (with the bind or flatMap operations.)

    4. Re:Wouldn't help by Chirs · · Score: 1

      Given that in the US there are approximately 40000 fatalities/year from car accidents, what conclusion do you draw?

    5. Re:Wouldn't help by Seakip18 · · Score: 1

      Amen!

      Sometimes, you need to see the program killed to realize you're doing it wrong.

      I recently discovered a horrible lapse of auditing in our program where user_id's were set = "". To the program, it's a valid ID. Had the original programmers made judicious use of null, this error would have popped up during testing and realized that "hey, we're not initializing this value!"

      --
      import system.cool.Sig;
    6. Re:Wouldn't help by ACMENEWSLLC · · Score: 1

      It's when I see stories like this that I am glad I program mostly on an i5 with RPGILE. While NULL is possible, it is usually only seen when interfacing with a PC application or if you bind to C/C++ programs or APIs. When I declare @variable I will inz() it, usually with *blanks or *hival (xFF) If I don't declare it, it could have whatever what is memory before but it's not = null. isnull *true.

    7. Re:Wouldn't help by javaxjb · · Score: 1

      As someone who works with both Java and RPG ILE (and sometimes C) on an i5 (or whatever IBM's nom du jour for the system is -- I've lost track), you just end up replacing one problem with another. I've seen plenty of RPG programs run away evaluating expressions against an uninitialized value until it's hard to discover the initial source of the problem. There are times where having a program blow up with a null value makes it a lot easier to find the problem at or close to the source. The whole topic of nulls seems to lead to omphaloskepsis and I can't help but think of the example from Godel, Escher, Bach where a series of unbreakable phonographs continue to be destroyed by a matching series of records that break them. This seems to apply most readily to some other posts in this topic which refer to clearly defining the meaning of null within a particular context (or replacing it with a special Object).

      I particulary like the example of "date of death" in a database: it is always unknown until it's known. I think null is the ideal (practical) way of representing it until the date is known. What would make a better substitution? A date before the day of birth? Or would that have to be more than 9 months before the date of birth? And what if the date of birth is not known. Should you enter the last known date alive? What if the person died shortly after the date was entered and you don't find out until later (this one, at least, could be useful in some applications)?

      Now, if a programmer calculates the age at death and doesn't check for null, I'd rather see the program blow up right then and there rather than pass something like negative ages through the system. When I first started writing OO programs, I got so frustrated with nulls that I made sure I initialized everything to something that represented the state in a meaningful way. As a result, the programs got overly complex and difficult to debug when checks got missed (that would have caused an error with nulls). When I learned to make judicious use of final fields amd variables where appropriate many of my longstanding issues with nulls went away. I tell the programmers I work with that null is your friend if you use it appropriately.

      --
      Programmers in mirror are brighter than they appear
    8. Re:Wouldn't help by Anonymous Coward · · Score: 0

      Not exactly. If every crash happens at 2am because the driver fell asleep at the wheel it wasn't the road's fault. It was the sun's fault for not being up that early.

    9. Re:Wouldn't help by jvkjvk · · Score: 1

      Are the accidents all on the same stretch of road?

    10. Re:Wouldn't help by Xtravar · · Score: 1

      Actually, all this NULL-reference crap is mostly a symptom of the "throw *Exception" programming pattern.

      Functions that could fail in returning a value should work more like this:
      bool Function(ref Object value)
      {
      }

      If you don't define your function like that, then yes, you have to check for NULL or catch an exception. How do you know what the function's going to do? Well, you don't unless you wrote it. So you do both or you do neither and thus begins a whole chain of problems.

      But then we get the whole whining about having long if-trees instead of try/catch blocks.

      (Alternatively, use a discrete integer return value for specific errors if you don't like the boolean.)

      --
      Buckle your ROFL belt, we're in for some LOLs.
    11. Re:Wouldn't help by Kupek · · Score: 1

      What Hoare is talking about is designing the language so that the entire concept of a null reference is impossible. That is, if you wrote a program that might result in a null reference, then your program would not compile.

    12. Re:Wouldn't help by jc42 · · Score: 1

      I recently discovered a horrible lapse of auditing in our program where user_id's were set = "".

      As late as the mid-1990s, there was a common bug in many unix systems, in which an entry in /etc/passwd with null fields was considered valid. And even better, a blank line would often be treated as an entry with all its fields blank. A null numeric field such as uid and gid would be treated as zero. This meant that if the password file contained a blank line, you could become super-user by typing all of 6 chars (counting the newline):
            su ""

      The null user name would match the first field in the blank line, the numeric uid was zero, and you were in.

      I learned about this in my first intro to unix, in 1981. I was duly impressed when I found the bug still alive in the systems used where I worked as a contractor in 1994. In a meeting one day, the group's manager asked if my debugging would be made easier if they told me the root password to the lab's test machines. I said that it wouldn't help, because if I needed root access, I just made my own root account, which was desirable because that way the accounting would keep my root use separate from other super-users, so we could tell which super-user had done what. All the lab machines had a blank line in the password file between the "system" and "user" accounts.

      But eventually they wanted to know how I made my own super-user accounts. Testing became more difficult after that, since their security people didn't understand why machines in the test lab should be so easily available to the people paid to use them for testing, and kept hiding the passwords from the people who needed them to do their job.

      It's also sorta fun to see how confused people can be about "null" values ...

      --
      Those who do study history are doomed to stand helplessly by while everyone else repeats it.
    13. Re:Wouldn't help by adiposity · · Score: 1

      And then the programmer wraps your code with a try catch loop and throws your exception...which is only slightly better than a null pointer exception.

      -Dan

    14. Re:Wouldn't help by mtopol · · Score: 1

      But the point is that in a huge number of situations you wouldn't need to check it. Checking for it all the time is something like using static methods (in Java) and doing "if instanceof" checks on the arguments all the time. That's the job of polymorphism! So, having a custom null-object for every object type would save the client a very big proportion of null-checks -- read "null errors." For example, one usually checks that a string is non-null and not empty; sums two Integers, always having to check BOTH for non-null; or, the most notorious of them all, just wants to see if two objects are equal. In all such examples the non-null check vanishes, resulting in code that is at the same time more elegant, more readable and more robust.

    15. Re:Wouldn't help by nuttycom · · Score: 1

      Hey, yeah! Let's go back to 1970!

      I much prefer to write as many parts of my program as pure functions as possible. If null is one language hole that caused a billion errors, mutable variables in places that they shouldn't be (i.e. just about anywhere that's not related to IO) have probably caused 10x that number of problems. Functions that mutate their arguments in-place are EVIL.

    16. Re:Wouldn't help by nuttycom · · Score: 1

      If they're not a developer at my company, that's not my problem.

      If somebody in my company using my code isn't willing to do their job properly and handle failure cases, that's great. My boss will be happy to fire them and find a replacement, and we'll all be better off as a result.

    17. Re:Wouldn't help by adiposity · · Score: 1

      The point is that you fixing your code doesn't make the calling code any better. If you returned a null pointer, he could check for that. If you throw an exception, he can handle it. Or he can just dump a stacktrace, just like he could fail to catch a null pointer exception.

      Formalizing ways to handle problems does not eliminate problems. It just describes a process by which to handle them. In contrast, if null pointers were not allowed, this would be a problem that simply couldn't occur.

      -Dan

    18. Re:Wouldn't help by nuttycom · · Score: 1

      Well, at least if I return a type that explicitly requires you to extract the data that you want from it, it is clear that the possibility of not returning data exists. If I simply returned null, there would be no way that the function signature would indicate this, and hence it's much more likely to go unchecked.

      Checked exceptions are in my mind a different sort of beast, since they circumvent the normal program flow. If I call a function returning Option, I can immediately bind it to another function returning Option and evaluate the result in one place. As part of this, I can provide sensible default values at any point along the chain. Exception handling is usually not nearly so clean.

      I agree that eliminating the use of null altogether would be a great deal better - my original post was simply pointing out a good way to do so in programs that people are writing today, without waiting for the compiler writers to catch up (and without the endless hand-wringing that would occur were they actually to eliminate null.)

    19. Re:Wouldn't help by adiposity · · Score: 1

      You're right, your approach is definitely an improvement. It wraps the condition in such a way to make the programmer at least consider the problem. Unfortunately, programmers are lazy, and they will always find poor ways of handling errors they trap. But at least you are giving them the option and making it clear.

      -Dan

    20. Re:Wouldn't help by Xtravar · · Score: 1

      Hey, yeah! Let's go back to 1970!

      Hey, it's still the best way to make code mostly portable between languages. Lowest common denominator = win!

      You can take your silly Prolog and go write... a calculator with it! Meanwhile I'll be writing a 5 page long switch statement for return values.

      --
      Buckle your ROFL belt, we're in for some LOLs.
    21. Re:Wouldn't help by Raenex · · Score: 1

      Checked exceptions are in my mind a different sort of beast, since they circumvent the normal program flow.

      Null return values eventually turn into null pointer exceptions, at least in Java. They are essentially the same principle. Where do you draw the line between the two? If call a parse function, should it throw an exception or return null if it fails? What do you do when you can't find a file on disk? What do you return when a network call fails?

    22. Re:Wouldn't help by nuttycom · · Score: 1

      The problem with allowing null values to propagate into null pointer exceptions is that the exceptions can be unrelated to the point of failure. Say that I have a method that returns a File, or null if that file is not found. If I take the results of that method and store it in an object (or worse, an anonymous inner class closure) that isn't used until later, the resulting NPE cannot be reliably prevented unless every use of the . If the method returns an Option instead, I have to explicitly deal with the failure case at the point in program flow where the method returns. This is particularly useful when it's possible to specify a reasonable default.

      To be clear, it's not that replacing null with an Option allows you to do anything that you couldn't otherwise do by checking for a null return type - it just means that the compiler forces you to think about what the behavior should be if no sensible result is returned. In an ordinary Java program, you're never quite sure which methods might return null, so the only way to be perfectly safe is to check the return value of every method call. This extra boilerplate makes code hideous. If, on the other hand, a library never returns null, then you can safely skip the null check and use the powerful features provided by Option to deal with missing results wherever they might be returned - and the compiler will force you to do so.

      The line between when to throw a checked exception and when to return an Option is a bit blurry; in general I use exceptions to indicate unexpected failure, and Option for situations where a missing return value might be expected. A classic example of an appropriate use of Option would be looking up a value from a Map - of course, the Java Map interface specifies a return value of null for when a key isn't found, but a more sophisticated Map interface that returns Option (such as the one in Scala) makes for much cleaner program flow. In the following, assume that baz is a method that may also return no result (null in the first case, Option in the second.) Compare:

      //java
      Map m = ...
      String foo = m.get("bar")
      if (foo == null) {
          return "gweep";
      }

      String bazed = baz(foo);
      if (bazed == null) {
          return "gweep";
      } else {
          return bazed;
      }

      //scala
      val m : Map[String,String] = ...
      return m.get("bar").flatMap(baz(_)).getOrElse("gweep")

  6. Re:Null is NOT just a value by AKAImBatman · · Score: 1, Interesting

    wouldn't the first thing you'd do in the system API design of any non-null language be, the creation of a singleton object instance of the superclass of all objects, named 'null' ?

    Umm... no? The first thing done is usually a superclass called "Object". If you don't extend anything else, you extend Object. Depending on the language, the superclass of Object would either be self-referential or the option to obtain a superclass wouldn't exist. (The latter being the "correct" solution. See my next statement for why.)

    Null is just a value

    That's actually a problem. Null is a piece of data that represents the absence of data. The paradox here should be obvious. If the data doesn't exist, why do we create data about it not existing? If I have no apples, do I have an object that represents my lack of apples? No, I simply have no apples. At best, I might have a special container for apples. If it's empty, then I can infer that I have no apples. Just as a program can infer the absence of data through an empty collection.

    Thirdly, a similar rant can be had against non-range checking of enums in C (but then warning against it in switches (WTF?)).

    There's a lot of things wrong with C as a language. Don't try to use those as arguments. (Remember, C is more or less high-level assembly. On the scale of comp-sci it barely even rates. Its popularity stems from the excruciating slowness of computers in days gone by.)

  7. Algebraic data types by Sneftel · · Score: 4, Informative

    The concept of "no null references" would be very limiting in a language without algebraic datatypes. You can think of null references as a sort of teeny limited braindead algebraic data type, actually. I get the feeling that much of the incredulity here stems from the posters not being familiar with languages that support them. If this describes you, check out Haskell and OCaML! They're the sort of languages that make you a better programmer no matter what language you're using.

    --
    The opinions stated herein do not necessarily represent those of anybody at all. Deal with it.
    1. Re:Algebraic data types by Anonymous Coward · · Score: 0

      Because forcing inherently procedural/algorithmic code into a functional paradigm makes for readable code, AMIRITE? Stop with the "functional languages are a panacea" bullshit already.

    2. Re:Algebraic data types by Chrisq · · Score: 1

      The concept of "no null references" would be very limiting in a language without algebraic datatypes.

      Not necessarily. You could mandate default constructors that would be invoked every time that an unreferenced object occurred, so Strings unless explicitly initialised would refer to "", user types to whatever the default constructor produced, and so on.

    3. Re:Algebraic data types by kschendel · · Score: 1

      Ah. Like the almost-universally hated original IBM PC keyboard, which "made you a better typist"...

      While AlgolW was a pleasant enough language, calling it "object oriented" is wildly optimistic. Perhaps the language Hoare envisioned was very different from the one I actually used,long ago.

    4. Re:Algebraic data types by Stephen+Ma · · Score: 1
      Because forcing inherently procedural/algorithmic code into a functional paradigm makes for readable code, AMIRITE?

      No, you're wrong, and there's no need to be so aggressive. No law says that algebraic datatypes can only appear in functional languages. They are in fact quite conceivable and useful in normal procedural languages. For example, see Pizza, a variant of Java; it has functional aspects but is very definitely procedural.

    5. Re:Algebraic data types by Estanislao+Mart�nez · · Score: 1

      Not necessarily. You could mandate default constructors that would be invoked every time that an unreferenced object occurred, so Strings unless explicitly initialised would refer to "", user types to whatever the default constructor produced, and so on.

      But that would be very limiting indeed. Basically, in that situation, you just make it a lot harder to encode "out of band" information like the absence of a value; if you encode something like "no input was provided" as the empty string, then your program cannot easily distinguish "no input was provided" from "the empty string was provided as input." You'd need to carry around some other piece of information, for example a boolean value, to distinguish between these two situations. If you did this a lot, you might find yourself putting the boolean value and the string together in a struct. But what you're doing then is basically your own ad-hoc implementation of an algebraic data type.

  8. Eiffel by Meor · · Score: 1

    Eiffel recently added void safety.

    1. Re:Eiffel by Anonymous Coward · · Score: 0

      My bro and I eiffeled your mom last night. High five!

  9. Arrogance? by Anonymous Coward · · Score: 1, Informative

    Is it not a tad arrogant to claim that he single-handedly is responsible for a billion dollars in mistakes? First, as an earlier poster remarked, the programmers themselves, or at least the current business context of programming, are perhaps more responsible. Second, while I'm aware that Tony Hoare is largely responsible for defining Algol -- though it was a committee effort -- it may just be on the edge of possibility that a high performance language such as C would have still included null references even if Algol did not. And Hoare's reference to Microsoft's work is nothing but PR; MSR is his current employer. Plenty of other earlier efforts have addressed null pointer dereferences; and of course certain classes of languages avoid the problem entirely.

    1. Re:Arrogance? by Chrisq · · Score: 1

      Not really, I will certainly print out his admission and have it ready for every project I work on in future ;-)

    2. Re:Arrogance? by Anonymous Coward · · Score: 0

      I am more inclined to feel lenient towards a claim that someone is responsible for a billion dollar loss, than if they claim to have produced a billion dollar benefit.

  10. The mistake was actually not having a standard by Nicolas+MONNET · · Score: 4, Insightful

    for Pascal type strings in C. The fact that null-terminated strings existed wasn't the problem, they make some sense in some respects, such as when you want to pass text of arbitrary length. But the real problem, the real bug was not having a standard way of doing real strings in C. Everybody had to do it himself, poorly. Had there been a standard, no matter how poor, it would have been a starting point to do something better if needed, and would have been better anyway for many uses than C strings. It would have avoided MANY vulnerabilities from common software.

    1. Re:The mistake was actually not having a standard by Vanders · · Score: 3, Interesting

      The problem with Pascal strings is that it's easy for a short-sighted implementer to paint themselves into a corner. It's all very well and good to say "The first two bytes in a string are used to indicate the length of the string" but then what do you do a decade from now when a 16bit string is laughably small? The benefit of NUL terminated strings is that there length is only limited by the memory available to you and yet are forward and backward compatible by decades.

    2. Re:The mistake was actually not having a standard by dunkelfalke · · Score: 1

      it can be solved by two things

      1) changing the const for the string length indicator width in the standard libary
      2) making the language using only the specified string length command by forbidding things like string_length:=mystring[0];

      --
      "It's such a fine line between stupid and clever" -- David St. Hubbins, Spinal Tap
    3. Re:The mistake was actually not having a standard by EvanED · · Score: 1

      ...but then what do you do a decade from now when a 16bit string is laughably small?

      Start tacking 32 bits in front. C has plenty of other places with implementation-dependent limits.

      If you always tack the computer's native word size in front, you'll almost always have the maximum length be the size of an address space (which is a length limit already).

      You get source code compatibility from this. Actual string objects don't have to be portable between a 16-bit and 32-bit implementation, because you almost never save information simply by doing a memory dump, and there will be lots more which isn't portable between those versions (like an 'int'). And if you could find a platform where moving the compiled code to a new system gives you more memory but still works (which seems unlikely since the pointer size would also have changed), if you've been living for years with shorter strings, you can probably continue to live with shorter strings.

      In any case, these problems seem very minor in comparison to the fact that, had Ritchie or whoever made decisions about strings in C provided strings as a first-class type or at least used a better de facto standard (a string = some struct), what I suspect to be the second-most common reason for buffer overflows could have been stopped.

    4. Re:The mistake was actually not having a standard by squiggleslash · · Score: 1

      Meh, then you're limited to 2^(#bits in length count) characters per string.

      I've always used my own custom string implementation, which uses linked lists of characters...

      --
      You are not alone. This is not normal. None of this is normal.
    5. Re:The mistake was actually not having a standard by metamatic · · Score: 1

      It's all very well and good to say "The first two bytes in a string are used to indicate the length of the string" but then what do you do a decade from now when a 16bit string is laughably small?

      You do what you should have done the first time, and use a humber (variable length binary number) for the string length. See Ted Nelson's Literary Machines.

      --
      GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
    6. Re:The mistake was actually not having a standard by Vanders · · Score: 1

      Start tacking 32 bits in front.

      Now your 16bit strings & 32bit strings are not portable across implementations, and you have to somehow know that which type of string you're using before you can use it.

      Actual string objects don't have to be portable between a 16-bit and 32-bit implementation

      Are you sure about that? I can think of plenty of situations where passing a simple bit of data between two platforms causes all sorts of problems without the added headache of having to deal with different "types" of strings, with different headers etc.

    7. Re:The mistake was actually not having a standard by mdmkolbe · · Score: 1

      Now your 16bit strings & 32bit strings are not portable across implementations, and you have to somehow know that which type of string you're using before you can use it.

      'int' values aren't portable in C/C++ either. They could be 32bit or 64 bit (I think 16 and 8 bit are also legal).

      That problem can be avoided at least today by using ptrdiff_t:

      typedef struct _string_t {
          ptrdiff_t length;
          char *data;
      } string_t;

      This code will ways have the "right" number of bits at the front to represent the length.

      Or if you don't like ptrdiff_t, or want something that works on older compilers you could just keep a pointer to both the front and the end like so:

      typedef struct _string_t {
          char *start;
          char *end;
      } string_t;

    8. Re:The mistake was actually not having a standard by Thiez · · Score: 1

      Simply define the size of the 'size header' as sizeof(pointer)? Using strlen on a system where a '16bit string' (I assume you refer to a 65536 byte string) is laughably small is laughably slow.

    9. Re:The mistake was actually not having a standard by EvanED · · Score: 1

      I can think of plenty of situations where passing a simple bit of data between two platforms causes all sorts of problems without the added headache of having to deal with different "types" of strings, with different headers etc.

      That's precisely why I say strings don't have to be portable. The fact that nothing else is portable either means that you already have to but a fair bit of effort into dealing with serializing the data in some portable fashion, and at that point a little extra effort to deal with the string header isn't going to be a huge deal. If you have some automatic method of dealing with structs already (some sort of IDL for instance), it may even be free.

    10. Re:The mistake was actually not having a standard by tolgyesi · · Score: 1

      At language design time, it could have been easy to say there are as many string types as integer types, like short string, long string, long long string, referring to the size field. Auto-extending them in a function call may be tricky though.

    11. Re:The mistake was actually not having a standard by Anonymous Coward · · Score: 0

      'int' values aren't portable in C/C++ either.

      Yes, and that small, simple, difference causes enough portability issues alone! Also we're lucky in many ways that historically C == UNIX and UNIX programs communicate with human-readable text, not raw numerical values, so INT_BITS has never been a direct consideration when sending data from system 'X' to system 'Y'. Inputting, processing and outputting text however, has always been very important in UNIX, which is why we're lucky we don't have Pascal-style strings! We have enough problems already dealing with character encodings...

      If you want to see what happens when you start to try and encode raw data in a totally platform neutral way, take a look at the ASN.1 spec some time, then think about how much simple 8bit ASCII text gets passed around the internet, and think yourself lucky you don't have to worry about stuff like that.

    12. Re:The mistake was actually not having a standard by MobyDisk · · Score: 1

      hat do you do a decade from now when a 16bit string is laughably small

      That problem pales in comparison to problem that null terminated strings caused: The developer allocates a fixed length line 20 characters, then finds it is too short.

    13. Re:The mistake was actually not having a standard by Anonymous Coward · · Score: 0

      Look into ASN1-style encoding.

      The first byte (or smallest addressable datum) is the length of the string, unless the value is the special value (in practice usually 255 or maxvalue for that datum) in which case the size is 255 plus the value of the second byte (datum), and so on.

      For most strings ( length less than 255 ) the storage overhead is the same as a null-terminated string, and you have immediate access to the length of the string. Even if the string is long enough to require a second byte, it's still a small fraction of the size of the string itself. On the processor load front, it seems to be an obvious win any time the length of the string is an issue as it takes log255(strlen) reads to determine the length instead of strlen reads. I recall there were some use cases where null-terminated strings performed better, but I can't recall what they are.

    14. Re:The mistake was actually not having a standard by prockcore · · Score: 1

      Or a 3rd thing.

      If the first byte has its high bit set, then there is another byte following that contains the next 7 bits of the length.

      So a string that's 80 bytes long would have 0x50 as its length byte, and that's the end of it.. 1 byte.

      A string that's 280 bytes long would have 0x98 as its first byte, and 0x02 as its second... 2 byte length field.

    15. Re:The mistake was actually not having a standard by Anonymous Coward · · Score: 0

      Hmm, isn't that easy to solve?

      Just say "The length of the string is first specified in a variable number of bytes (minimum 1). Starting from the first byte, if that byte's first bit is 1, the following byte is also part of the number which indicates the length. The last byte's first bit should then be 0.
      E.g.:
      1abcdefg 1hijklmn 0opqrstu

      would imply that the binary number abcdefghijklmnopqrstu (where each letter is a binary digit) should be set to the value of the string length....

      (I seem to remember from my classes 10 years ago that the file tables of the file system used by default by Slackware then - I don't remember which FS - was using something like this principle to prevent upper limits to FS size....)

      Same principle could be used in Integers also, if one wished.

      I never considered the overhead of this implementation, but of you probably could....

    16. Re:The mistake was actually not having a standard by steelfood · · Score: 1

      Strings are not arrays of bytes. A 16-bit limit is difficult to hit. A 32-bit limit is even less feasible. Even if a 4-billion character string existed (2 billion unicode), nobody would actually try to fit the entire 4 billion characters into memory. They'd optimize it using some sort of stream.

      So the chances of short-sightedness is very small, especially with a sufficiently large initial maximum.

      Besides, if there was a 16-bit character limit and you hit it, then just use an array of strings.

      --
      "If a nation expects to be ignorant and free in a state of civilization, it expects what never was and never will be."
    17. Re:The mistake was actually not having a standard by johanatan · · Score: 0

      Yea, and then you have to scan the entire string just to find out how long it is--a O(n) operation for something that should be O(c).

    18. Re:The mistake was actually not having a standard by dunkelfalke · · Score: 1

      a very good idea indeed :-)

      --
      "It's such a fine line between stupid and clever" -- David St. Hubbins, Spinal Tap
    19. Re:The mistake was actually not having a standard by Lehk228 · · Score: 1

      pattern the length as such that the first byte indicates length unless it is max int, in which case the next byte is also used, recursively.

      if the string happens to be an even max int size follow with a 0.

      --
      Snowden and Manning are heroes.
    20. Re:The mistake was actually not having a standard by mdmkolbe · · Score: 1

      The strings passed around the network or in files are not null terminated either. They have to deal with the possibility of there being actual null values in the strings. If anything they are closer to the type presented above because they use an out-of-band encoding (e.g. TCP, file-system meta-data) to determine where the strings terminate.

      The 'string' struct is really just an out-of-band encoding for the 'data' portion of the struct. When you print a string you obviously wouldn't print the size at the front (unless the format you are printing needed it) just as you don't print the null at the end of the string.

    21. Re:The mistake was actually not having a standard by PDAllen · · Score: 1

      What's wrong with a few different variants of string? It's not as if there is only one type of integer or 'real' variable...

      16 bit strings are not huge, but a 32 bit string is a reasonable chunk of data; and we won't run into trouble with 64 bit strings for a while yet. So - STR for 8 bit, LSTR for 32 bit and XSTR for 128-bit strings will do for the next millennium or so... seems this might be familiar?

  11. Correcting the Billion Dollar Mistake by ekabanov · · Score: 1

    A write-up on this very topic from the Java perspective after a discussion at the JFokus conference: http://dow.ngra.de/2009/02/01/correcting-the-billion-dollar-mistake/

  12. How else would you terminate them? by wiredog · · Score: 1

    In a low-level language like C or assembly, anyway? The only workable alternative I ever saw was to store the length in (or with) the string, which can be very wasteful of memory.

    1. Re:How else would you terminate them? by Talchas · · Score: 1

      On a 32-bit platform it adds three additional bytes to the string over a null terminator. If you have thousands of very short strings, it could be wasteful of memory. Most times you have much longer strings, and in even the case of say a 20 character string, 21 bytes vs 24 bytes is generally pretty insignificant.

      --
      As the Americans learned so painfully in Earth's final century,free flow of information is the only safeguard against...
    2. Re:How else would you terminate them? by kLaNk · · Score: 1

      In a low-level language like C or assembly, anyway? The only workable alternative I ever saw was to store the length in (or with) the string, which can be very wasteful of memory.

      How is storing the length wasteful of memory? 99% of the time I'd guess as much space would be used in storing a null character as would be consumed storing the length of the string itself.

    3. Re:How else would you terminate them? by camperdave · · Score: 1

      If you prefix the string with a byte containing the length of the string, you are no worse off than postfixing the string with a zero byte. Besides, memory is cheap. It has been for decades. Face* was right. C needed a string type, and since it wasn't there, people implemented it badly.

      * Face is what I call people when I can't remember (or can't be bothered to look up) someone's name. It's a cross between "What's his face" and the A-Team character.

      --
      When our name is on the back of your car, we're behind you all the way!
    4. Re:How else would you terminate them? by jcochran · · Score: 1

      Wasteful?

      Not at all.
      Look at some of the other languages at the time that had string lengrh limits of 255 characters. You'll find that the limit of 255 wasn't random. So in that case you can terminated a string with a zero byte costing 1 byte to indicate the length, or you can explicitly store the length in 1 byte at the beginning of the string. Both methods have an overhead of 1 byte.

      But what if you want a string with a length greater than 255 characters? Then you will have an extra bit of memory overhead. Namely store the length of the string in 2 bytes for a nice limit of 65535 characters. And if you want a string longer than 64K, just use 4 bytes for a max length of 4 gig.

      Nice thing about this, is that as your desirable string lengths go up, the amount of memory you have also goes up, so the overhead is still quite reasonable.

      Heck, in order to not have a lot of overhead for encoding the string lengths, you could use something like the encoding that's used for UTF-8 at the beginning of a string to encode the length of the string.

      0 to 127 characters long - Prefix with 0xxxxxxx
      128 to 2047 characters long - Prefix with 110xxxxx 10xxxxxx
      2048 to 65535 characters long - Prefix with 1110xxxx 10xxxxxx 10xxxxxx
      etc.

      And if the upper limit of only 2^31-1 characters is deemed too short, you could instead use the method of encoding OIDS using BER. e.g

      0 - 127 = 0xxxxxxx
      128 - 4095 = 1xxxxxxx 0xxxxxxx
      4096 - 2097152 = 1xxxxxxx 1xxxxxxx 0xxxxxxx

      No real upper limit to this length encoding method. And by having an explicit length in the string, there's no real limitation on the contents of the string.

      This is a cat that has a lot of ways to be skinned.

    5. Re:How else would you terminate them? by Anonymous Coward · · Score: 0

      A one byte length indicator versus a one byte terminator.

      Or imagine the awesome waste generated by using two bytes to store the length of a string several thousand bytes long. A worst case scenario of about 00.5% waste must mean the end of the world as we know it!

    6. Re:How else would you terminate them? by AlecC · · Score: 1

      How much memory will you pay to avoid one bug? Null terminated strings were invented when 64k was a large memory for a single computer. We have moved rather a long way from that. I would spend a *lot* of ram to save one bug in delivered code.

      --
      Consciousness is an illusion caused by an excess of self consciousness.
    7. Re:How else would you terminate them? by Jerry+Coffin · · Score: 1

      How is storing the length wasteful of memory? 99% of the time I'd guess as much space would be used in storing a null character as would be consumed storing the length of the string itself.

      You're basically right: the vast majority of strings are short enough that a single byte could hold the length. The problem is that if you decide to use only a single byte to hold the length, the design limits ALL strings to 255 characters -- and unfortunately, even though most strings are short, a few are long. A good design should be optimized for the common case, but allow anything that's at all reasonable.

      There are, however, alternatives to NUL-termination to allow that. One example would be to have the initial byte hold the length for strings up to size X, but also have a value (or two) that signal the the next N bytes hold the real length. For most strings, this would waste no space at all. It would waste a little space only for the few that are quite long.

      Of course nothing is free -- the penalty in such a case would be extra complexity in the string handling code.

      --
      The universe is a figment of its own imagination.
    8. Re:How else would you terminate them? by darkwing_bmf · · Score: 1

      The compiler can keep track of the string length if memory is a concern. You could have "safe" string (array) specific keywords for indexing or referencing the elements of the string if that is your desire. You could still use 0 as a terminator if the actual length is smaller than the maximum length. And the 2nd point is, why would memory be such a concern anyway? When you're dealing with strings, the string itself takes far more space than the integer it takes to store the length.

    9. Re:How else would you terminate them? by psetzer · · Score: 1

      Unless you're manually packing string constants into memory, the space used by a string is the size of the buffer. Even packed, alignment issues mean the 3 bytes aren't usable without extra effort and performance costs for misaligned memory accesses. On a microcomputer which is extremely space-constrained but can access any spot in memory without consideration of alignment it makes sense. On a modern PC or even many embedded systems these days, not so much.

      --
      "Anyone who attempts to generate random numbers by deterministic means is living in a state of sin." -- John von Neumann
    10. Re:How else would you terminate them? by Anonymous Coward · · Score: 0

      In a low-level language like C or assembly, anyway? The only workable alternative I ever saw was to store the length in (or with) the string, which can be very wasteful of memory.

      Or save a lot of memory, as you don't need to scan for the length of a string repeatedly.

      You may even share the same length word between your string and memory routines.

    11. Re:How else would you terminate them? by Anonymous Coward · · Score: 0

      One byte? Now that would have been a great excuse back in school, when the teacher demanded "at least 10 pages".

      "Sorry, but my word processor uses one byte for the length, so I can only write 255 characters.

  13. Pass by reference by hobbit · · Score: 4, Informative

    I'm raised on C-style programming languages, and have always used null pointers/references, but I am having trouble of grokking null-reference free language.

    Take a look at C++, in which you can declare methods to be "pass by reference" rather than "pass by pointer". Although the former is actually really just passing a pointer too, the semantics of the construct make it impossible to pass NULL.

    --
    "Wise men talk because they have something to say; fools, because they have to say something" - Plato
    1. Re:Pass by reference by johannesg · · Score: 2, Informative

      ... the semantics of the construct make it impossible to pass NULL.

      void bar (int &intref)
      {
          intref++;
      }

      void foo ()
      {
          int *intptr = NULL;

          bar (*intptr);
      } // learn something new every day!

    2. Re:Pass by reference by Anonymous Coward · · Score: 0

      the semantics of the construct make it impossible to pass NULL.

      Emphasis mine. Wrong, actually.

      /* g++ -W -Wall -Werror -pedantic wrong.cpp */
      #include <iostream>
      void possible (int& ref) { std::cout << &ref << std::endl; }
      int main (void) {
        possible (*(int*)NULL);
        return 0;
      }

      Note: Bad things happen if you try to read or write the value of reference when you pass NULL, but the example above doesn't crash because it only outputs the address of the reference.

    3. Re:Pass by reference by Chris_Jefferson · · Score: 3, Informative

      According to the C++ standard, as soon as you dereference NULL, you are off into the nasty old land of undefined behaviour, and all kinds of horrible things can occur to you.

      --
      Combination - fun iPhone puzzling
    4. Re:Pass by reference by OneSmartFellow · · Score: 1

      Although the former is actually really just passing a pointer too...

      No, it's not.

      A reference is an alias, not a pointer.

    5. Re:Pass by reference by Anonymous Coward · · Score: 0

      Nope, converting null pointer to reference is well defined, as is this: ((ptrdiff_t)&((struct FILE *)NULL)->n)

    6. Re:Pass by reference by 2megs · · Score: 1

      There's no real protection, because ultimately references just come down to syntactic sugar. In a large enough project, where foo(), bar(), and baz() below are implemented in different files by different teams, it's entirely possible to end up with something like this:


      struct A { int value; };

      void foo( A & ref ) { ref.value = 17; }

      void bar( A * ptr ) { foo( *ptr ); }

      void baz() { bar( NULL ); }

    7. Re:Pass by reference by Anonymous Coward · · Score: 0

      C++ forbids applying operator* to NULL. I think your example is implementation-defined (may not work) because some architectures fault when an invalid address (other than NULL) is loaded into a pointer register.

    8. Re:Pass by reference by deadlinegrunt · · Score: 1

      I missed the part of this particular conversation where "..."pass by reference"...make it impossible to pass NULL..." and the use of typecast are the mechanism for proving the original assertion incorrect; the semantics of passing by reference instead of passing by pointer.

      As an aside those are C-style typecast and use none of the C++ typecast semantics specifically made ass ugly in order to expose potentially dangerous characteristics.

      "In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." - Bjarne Stroustrup

      I suppose this is a solid example of why this quote exist.

      --
      BSD is designed. Linux is grown. C++ libs
    9. Re:Pass by reference by Anonymous Coward · · Score: 0

      According to the C++ standard, as soon as you dereference NULL, you are off into the nasty old land of undefined behaviour, and all kinds of horrible things can occur to you.

      And that's supposed to constitute an improvement?

    10. Re:Pass by reference by Anonymous Coward · · Score: 0

      That will crash because of the dereference, not the function call. gb2comp sci classes.

    11. Re:Pass by reference by deepestblue · · Score: 1

      Well, you need to take GP's point to its logical conclusion - use references everywhere. The problem with C pointers is that they have overloaded semantics - they're used for pointing to heap memory (which is the only place you need NULL) as well as for call-by-reference (for performance). C++ obviates the need for pointers in both instances. No, I'm not saying I never use pointers in C++, but they're rare, as rare as say, the "static" keyword.

    12. Re:Pass by reference by Anonymous Coward · · Score: 0

      How are you creating a reference there?

      (ptrdiff_t) &((struct FILE *) NULL)->n);

      ((struct FILE *) NULL) has type (struct FILE *), which is a pointer type.

      &((struct FILE *) NULL)->n) has type (N *) where N is the type of the field 'n' in 'struct FILE'.

      The (ptrdiff_t) casts (N *) into a ptrdiff_t type, which is presumably a signed integral type.

      Where do references come in?

    13. Re:Pass by reference by Kupek · · Score: 1

      The point is that the example compiles, even though the behavior is undefined.

      What Hoare is talking about is designing a language such that null references are impossible.

    14. Re:Pass by reference by mepperpint · · Score: 1

      Agreed, this is just another example of gcc failing to follow the spec. gcc is known to optimize away side-effects such as segmentation faults that might occur from a pointer dereference which is optimized away or a divide by zero error from a division that has been optimized out. It's really annoying that gcc thinks it's ok to change the meaning of programs in this way when it's optimizing them.

    15. Re:Pass by reference by norton_I · · Score: 1

      That is a pretty bad example. C++ references hardly count as references since you can't reassign them. They are really just syntactic sugar to make operator overloading look nice and reduce the number of -> operators. They cannot be used alone to create complex data structures.

      A better example would be references in lisp, perl, or java. They solve many of the problems of C/C++ pointers. They can't be out of bounds. They must respect the type safety of the language. They can't point to an invalid or destroyed object due to garbage collection. However, they all support a null reference.

      Maybe there is a better way to do this where you don't ever need null references, but I know two things for certain 1) SQL is not it 2) People will still make errors where data they expect to be there is not.

    16. Re:Pass by reference by Anonymous Coward · · Score: 0

      It's not impossible to pass a NULL to a reference, you might have to go out of your way to do it though:

      int &function()
      {
            int* nullref = NULL;
            return *nullref; // wicked, evil, naughty code!
      }

    17. Re:Pass by reference by shutdown+-p+now · · Score: 1

      Nope, converting null pointer to reference is well defined, as is this: ((ptrdiff_t)&((struct FILE *)NULL)->n)

      It's not. From ISO/IEC 14882:2003, 8.3.2[dcl.ref], p.4:

      "A reference shall be initialized to refer to a valid object or function. [Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the object obtained by dereferencing a null pointer, which causes undefined behavior."

      The expansion that you've offered is undefined, too. It's a typical implementation of offsetof (though not in the recent versions of gcc - have a look!), but a specific implementation is free to use that, because the implementers can guarantee a particular behavior for their implementation, and can safely rely on it. In portable C++ code, however, this is undefined.

    18. Re:Pass by reference by forgoil · · Score: 1

      As usual you can screw things up in C++, but the point is that if you code using references and don't adhere to unneeded & and * trickery you can more easily spot problems in your code.

      This is the very reason I do not like C++, because you always get people writing a lot of trickery that ends up as a lot of defects and problems. It requires a whole lot more out of the developers if you are going to use C++. A whole lot more.

      I also want to add that in all fairness the above poster might very well understand the true reason for references and just wanted to point out that noone using C++ will ever be safe.

    19. Re:Pass by reference by OneSmartFellow · · Score: 1

      C++ references hardly count as references since you can't reassign them...

      I think your definition of reference needs re-evaluating if you wish to use re-assignment.

      A reference to an object is just what it says. The reference is just another 'name' for the original object identifier. It doesn't make sense to 'reassign' a reference.

      Example:

      int A = 0;
      int& B = A;
      'B' refers to an integer object also refered to as 'A'. So, you can change the value of the integer object instance through either reference ('A', or 'B'), but just as you can't change which integer object instance that 'A' refers to, neither can you change which integer object instance that 'B' refers to. That wouldn't make any sense. Remember, you're the one told the compiler that you wanted to refer to that object as 'A' or 'B'.

      I imagine that each member of your family has a name, and probably several other terms of endearment (references). You don't then use their name to refer to somebody else. Of course, sometimes you get name clashes (two people share the same name), but then you usually find you have to qualify their name (namespace), or rely upon context (scope) to know which person that you are referring to.

    20. Re:Pass by reference by Raenex · · Score: 1

      Agreed, this is just another example of gcc failing to follow the spec. gcc is known to optimize away side-effects such as segmentation faults that might occur from a pointer dereference which is optimized away

      gcc is not in error if the specification says the behavior is undefined. The problem is all the undefined behavior that C++ allows in the name of efficiency.

    21. Re:Pass by reference by badkarmadayaccount · · Score: 1

      Sounds good to me.

      --
      I know tobacco is bad for you, so I smoke weed with crack.
  14. Should have been patented! by fprintf · · Score: 1

    The concept of the null value should have been patented. If so, it would have validated that patents in software can be a good thing by stopping the destructive spread of bad ideas in the same way they stop the spread of good ones.

    Either that, or whoever invented the concept would be far richer than Bill Gates, Larry Ellison, and Steve Ballmer combined!

    --
    This post brought to you by your friendly neighborhood MBA.
  15. K&R's null-terminated string in C by peter303 · · Score: 1

    They should be shot for that one :-) This is lead to so many costly buffer-overflow virus attacks. Early languages like FORTRAN and COBOL had safer strings, but not as elegant as C. You had to pre-declare string storage size in early compilers.

    1. Re:K&R's null-terminated string in C by Anonymous Coward · · Score: 0

      Uh. In C you also pre-declare string storage size. You have a problem only if you use gets instead of fgets, sprintf instead of snprintf, or strcpy(dest, src) instead of strncpy(dest, src, n); dest[n-1] = '\0', etc.

    2. Re:K&R's null-terminated string in C by FlyingGuy · · Score: 1

      No, you are wrong. C is a small elegant language you can do big things with. K & R did it right the first time, period.

      All those "costly buffer-overflow virus attacks" were the fault of idiots who were just to lazy to do proper bounds checking.

      --
      Hey KID! Yeah you, get the fuck off my lawn!
  16. It's not that NULL pointers are a problem by wiredog · · Score: 1, Informative

    It's unitialized pointers (and, for that matter, other variables) that are the problem. At least in assembly and C/C++. I don't think I ever had cause to use pointers in Perl or Python. Or C#. Null pointers or zero values in other variables are easy to test for anyway. It's the uninitialized variables that bite you in the ass.

    1. Re:It's not that NULL pointers are a problem by Abcd1234 · · Score: 1

      I don't think I ever had cause to use pointers in Perl or Python. Or C#.

      Umm... what? Every single one of those languages has the concept of a pointer/reference that is virtually inescapable, and every one has a concept of undef/nil/null. Or have you never used a class in Perl (which is just a blessed reference), or a non-value-type in C# (which is stored and passed as a reference to the actual object)?

      Honestly, do you even know what a pointer is, conceptually??

    2. Re:It's not that NULL pointers are a problem by jgtg32a · · Score: 1

      How did you get by never using a pointer in Perl?

      It seems that it is the only way to do anything in that language.

      On one assignment I had to create one scalar and use it as a pointer to a hash where the keys were the different data types and that was were all of the variable were then I did the rest of the program from there. It was a massive brain fcuk for a while but I had a rather good understanding of how to use pointers afterwords.

    3. Re:It's not that NULL pointers are a problem by Anonymous Coward · · Score: 0

      I don't think I ever had cause to use pointers in Perl or Python. Or C#

      You used them lots. You just weren't allowed to do pointer maths on them so you didn't think of them as pointers. Take List x = new ArrayList(); List y = x; - x is a pointer to a List, as is y. And they point at the same area of memory

    4. Re:It's not that NULL pointers are a problem by Anonymous Coward · · Score: 0

      Perhaps he meant he has never had to define a pointer object. In python every object is a pointer to the object. I haven't used C# or Perl (I really should though).

      But in C, C++ and assembly pointers have to be manually created, creating the possibility of a null pointer.

    5. Re:It's not that NULL pointers are a problem by Anonymous Coward · · Score: 0

      Every single one of those languages has the concept of a pointer/reference that is virtually inescapable, and every one has a concept of undef/nil/null

      True, but I would argue that the GP meant explicit uses of C-like pointer variables, rather than use of variables with reference (non-value) semantics. You might be letting your knowledge of the implementation color your view of the design.

      Consider calling a function taking a value-semantics argument: what prevents a compiler from passing the value by reference, and then disallowing modification of it? Or making a read-only view of it instead of a full copy? From a design stand-point, all that has to be honored is the immutability of the object in the caller frame. This is usually accomplished by copying in C-like languages, but it doesn't have to be.

      Python seems to be all the rage for example-making these days (good and ill), so how would Python pass a value argument? We immediately run into trouble: Python doesn't have value-like function arguments, because Python doesn't have value-like variables. Variables in Python are dynamic aliases to objects (in C-like languages they are static aliases, fixed on entry to the block). In Python, the notion of value semantics vs reference semantics is moved to the object itself: objects are either immutable (value-like) or mutable (reference-like). So, in Python, a value-like object is passed to a function by reference, and immutable object semantics prevent the object in the caller frame from being modified. Where's the pointer here? Plenty to choose from, but none of them are part of the design--they are all implementation details.

      That said, I use pointer-like variables in Python code all the time. Bound method pointers and curried function pointers are exquisitely powerful.

    6. Re:It's not that NULL pointers are a problem by shutdown+-p+now · · Score: 1

      Null pointers or zero values in other variables are easy to test for anyway.

      They are. The problem is that people usually don't do that everywhere they must, and the result is that a null pointer/reference gets silently propagated, until at last some piece of code (usually not the one who created the null reference when it shouldn't have) tries to perform some action that is invalid for null (normally call a method on it), and then it all blows up at run-time. Which is certainly a problem.

  17. Trouble is that even if you remove NULL-refs by Kjella · · Score: 1

    You'll just have developers replace it like:

    $foo = NULL;
    getRef( $foo );
    if ( $foo != NULL ) {
            doSomething( $foo );
    }

    with

    $foo = "dummy";
    getRef( $foo );
    if ( $foo != "dummy" ) {
            doSomething( $foo );
    }

    Basicly, you can write any null code as non-null code just like you can hammer a square peg in a round hole. All you'd have is that instead of missed null checks you'd have missed dummy checks and it's be even less sane and understandable. Compared to every other way of enforcing error flagging the null references are the KISS solution. Though I much prefer the object oriented way where "isNull()" is the opposite of "isValid()" and that'll try to behave "nice" (usually by doing nothing and return error values) when something calls it instead of killing the application.

    --
    Live today, because you never know what tomorrow brings
    1. Re:Trouble is that even if you remove NULL-refs by Laxitive · · Score: 2, Informative

      We're not talking about not having null references at all. Nullable references are in fact very useful in many situations, as you point out.

      The problem is that in many languages, it is not possible to describe a non-nullable type. I.e. a type that guarantees that the value it annotates is not null.

      This is useful because the vast majority of actual code doesn't really deal with 'null' references, and in fact will break if 'null' references are passed in. Right now, there are two ways to ensure your code is safe:

      1. make assertion-type checks everywhere. This is a pain in the ass to write and maintain compared to providing a non-nullable type. It's also slow to throw in unnecessary null checks everywhere during runtime.

      2. don't check aggressively, but ensure in an ad-hoc way that all not-null preconditions are met. Basically, you just make sure to never call the relevant methods with null values. This has the problem that you have to keep track of EVERY SINGLE PLACE a null may be introduced and eventually find its way into the method. This may be easy in simple applications, but can become very tedious in large applications.

      Providing a non-nullable type constructor saves all of those things. The compiler can ensure that a NULL never makes it into a variable marked not-null. You don't have to care about it. You can split your code up into the sections that are "pure" and sections that are "impure", and keep all your null-sanity-checking in the (what should be a relatively small) 'impure code', which calls into the pure code, with the compiler ensuring the calls are all valid.

      No work, just a simple type annotation. That's the potential.

      -Laxitive

  18. An was an even Bigger mistake: by Wargames · · Score: 5, Funny

    Zero. The bane of all. It was the gateway math to all modern problems. It would be so much simpler with just countables. Surely the current crisis, measured in trillions would look so much better without all those zeros.
    Whoever it was who invented zero should take responsibility for all the worlds problems, ex nehilo.

    --
    -- Each tock of the Planck clock is a new world and here we are still life. --
    1. Re:An was an even Bigger mistake: by AKAImBatman · · Score: 2, Informative

      Null predates zero in the western world. The Romans had no number for zero, but they did represent the concept of nothing with the word 'nulla'. Thus if I had IIII denarii and spent all IIII, I would have nulla remaining. i.e. "nothing".

      As an aside, the numbering is correct. The subtractive form of IV for four is a more modern construct that was not in common use during the Roman empire.

      If you're still hell-bent on finding who defined zero as a legitimate numerical value, you'd need to look to 9th century India. Their mathematics had evolved far enough to where they stopped asking the philosophical question of "is nothing a number?" and simply used it to get math completed.

    2. Re:An was an even Bigger mistake: by JustNiz · · Score: 1

      The ancient Babylonians, Mayans and Hindus all independently invented/discovered the concept of 0. Seriously.

    3. Re:An was an even Bigger mistake: by AKAImBatman · · Score: 1

      The Babylonians did not have zeros. They simply omitted the number, leaving a space in its stead. Eventually they began using a symbol in certain circumstances to clarify the empty space, but it was not a true "zero" value as we think of it today.

    4. Re:An was an even Bigger mistake: by sneilan · · Score: 0

      I bet the this programmer who invented the null reference is laughing all the way to bank.

      --
      "I like it when the red water comes out.."
    5. Re:An was an even Bigger mistake: by DaFallus · · Score: 1

      I know you were joking but people throughout history have shared this view of the number zero. Back in college I read The Nothing that Is: A Natural History of Zero and apparently the number zero was considered to be evil by some since it symbolizes nothingness. Some cultures simply used a blank space to represent "nothing". It has been a while since I read the book but I remember it being very interesting and even insightful for a book about the history of a number.

      --
      No one cares what your captcha was

      Houston TX, USA
    6. Re:An was an even Bigger mistake: by jc42 · · Score: 2, Insightful

      Ki>Zero. The bane of all. It was the gateway math to all modern problems. It would be so much simpler with just countables. ... Whoever it was who invented zero should take responsibility for all the worlds problems, ex nehilo.

      Heh. I'm glad someone managed to bring up what should be obvious to anyone competent in basic math. While reading the posts here, I kept thinking "Yeah, and you have the same sort of problems if you allow your numbers to include zero." But I figured that the folks making the silly arguments probably wouldn't understand that sort of verbal irony, so I just let it pass.

      I can easily imagine variants of most of the arguments here being used thousands of years ago against the individuals in India and Central America that started casually using that weird "0" symbol in their calculations. "What's the need for something that doesn't represent anything?" "I only need to count things that exist; there's no reason to count things that don't exist." And on and on.

      This whole discussion does sorta put a limit to any claims of technical competency on the part of the "tech nerd" population of /.

      (And to I need an extra . at the end of that sentence? That oughta be good for a long discussion, as well as the question of whether or not the final ')' in this sentence balances the initial '('. ;-)

      --
      Those who do study history are doomed to stand helplessly by while everyone else repeats it.
    7. Re:An was an even Bigger mistake: by Estanislao+Mart�nez · · Score: 2, Interesting

      Zero. The bane of all. It was the gateway math to all modern problems. It would be so much simpler with just countables. Surely the current crisis, measured in trillions would look so much better without all those zeros.

      Yeah, I know this is a joke, but I've still got to point out the following: a positional numbering system doesn't actually need a zero digit. Throw out zero, and use instead a digit 'X', whose value is ten. Then you get:

      1, 2, ..., 9, X, 11, 12, ..., 19, 1X, 21, ..., 98, 99, 9X, X1, X2, ..., X9, XX, 111, ...

      8X = 8 * X + X (ninety)

      X2 = X * X + 2 (one hundred two)

    8. Re:An was an even Bigger mistake: by againjj · · Score: 1

      The appropriate comparison to numbers would be NaN, in my opinion. Should we allow such a thing? Depends on what you are doing.

    9. Re:An was an even Bigger mistake: by badkarmadayaccount · · Score: 1

      <nazi type="parsing"> head explodes </nazi>

      --
      I know tobacco is bad for you, so I smoke weed with crack.
  19. Bad analogy. by morgan_greywolf · · Score: 2, Funny

    Could you try a better analogy. I think we might all understand a car analogy better...

    1. Re:Bad analogy. by Anonymous Coward · · Score: 0

      Could you try a better analogy. I think we might all understand a car analogy better...

      Consider the situation of cars. If you have a car, then something is in your possession. If you don't have a car, what do you have? Do you have some sort of object that depicts your lack of a car? Obviously not. Yet in the world of computers, we have this special piece of data that shows our lack of data. It's a bit like getting a Segway since you have no car. The Segway accomplishes nothing except to fill a space that does not need to be filled.

      Moral of the story: the Segway == NULL

    2. Re:Bad analogy. by Pervaricator+General · · Score: 1

      It's like when I was 16 21 and had no car...

    3. Re:Bad analogy. by Pervaricator+General · · Score: 1

      D'oh! It's like when I was 16^?^?21 and had no car...

    4. Re:Bad analogy. by clone53421 · · Score: 1

      If you don't have a car, what do you have? Do you have some sort of object that depicts your lack of a car?

      Yes, it's called a driveway.

      The uninitialized space is still there. It just doesn't have a car in it. "Pavement" is NULL.

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    5. Re:Bad analogy. by AKAImBatman · · Score: 1

      "Pavement" is NULL.

      Nope. Pavement is a collection. Depending on the size of the collection it may have enough "memory" for one car, or for millions. (We call the latter an "interstate".) An absence of a car is simply an empty collection.

    6. Re:Bad analogy. by clone53421 · · Score: 1

      The space is still there, though. What it contains is "pavement", and "pavement" is NULL.

      Now, if you add "car" to "pavement", the space no longer contains NULL. If NULL is also 0, then "pavement" + "car" conveniently equals "car" and we don't even think about the pavement any longer, which is what confused Anonymous Coward a few posts back.

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    7. Re:Bad analogy. by AKAImBatman · · Score: 1

      The space is still there, though.

      Does a collection disappear when it is empty?

      What it contains is "pavement", and "pavement" is NULL.

      Stop saying "there is no spoon". It's right there. The pavement exists no matter how much you want it to disappear while there are no cars on it*. Since it is a physical object that must be maintained, it is NOT analogous to NULL. NULL is data that indicates the absence of data. (Which actually doesn't make sense in the real-world, but I digress.) The pavement is a collection. It is a thing that holds zero to many of something else.

      Now, if you add "car" to "pavement", the space no longer contains NULL.

      If you were referring to the space ABOVE the pavement, then I could agree with you. There's nothing there. (If you ignore the atmosphere for a moment.) That is NULL. Which is to say, *nothing*. There is nothing there. Which is exactly the meaning of "null"; a word which derives from the Latin word "nulla" which means... (wait for it)... "nothing".

      * Putting aside quantum states while the pavement is not being observed.

    8. Re:Bad analogy. by acohen1 · · Score: 0

      The state issues you a title even if you have no car?

    9. Re:Bad analogy. by ghqman · · Score: 1

      How about a joke analogy:

      Man in a diner: I'd like a coffee with no cream.
      Waitress: Sorry, we don't have cream, you'll have to have it without milk.

    10. Re:Bad analogy. by clone53421 · · Score: 1

      My point is, the memory has to contain something. If there's nothing to put there, that something is NULL. Plain and simple.

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    11. Re:Bad analogy. by AKAImBatman · · Score: 1

      My point is, the memory has to contain something.

      What memory? There is no memory used if there is no reference. Ergo, there is no need for NULL. NULL only exists because it was easier to develop as a solution rather than making the underlying data structures mutable.

      If there's nothing to put there, that something is NULL.

      If there is nothing to put there, there is nothing. Poof. Nothing. No need for NULL.

      Watch:

      var x = {y: 10};
       
      delete(x.y); //POOF!
       
      if(!x.y) alert("Nothing there, chief");

      As an underlying data structure, y has just disappeared from the map that was holding it. Once the 'y' reference was deleted (no NULLs!) there was *nothing*. No reference, no pointer, nada, zip, zilch, none, nulla, no-thing. The data structure simply stopped including it.

    12. Re:Bad analogy. by Saija · · Score: 1

      maybe if you name your x object something like car... hehehe

      by the way, your post in this thread are so insightful, thanks

      --
      Slashdot ya no es que lo era! ;)
    13. Re:Bad analogy. by clone53421 · · Score: 1

      NULL only exists because it was easier to develop as a solution rather than making the underlying data structures mutable.

      Well, bingo. Care to try?

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
  20. Null as a concept by JustNiz · · Score: 5, Interesting

    Stroustrup's "C++ Programming Language" book introduces a concept called "resource acquisition is initialisation" that was eye-opening enough to me that it forever changed the way I think about code, and also seems relevant to your point.

    The basic idea is that an object is always meant to represent something tangible. As an example, consider the design of file object that abstracts file I/O operations. As a developer, I've come across this one several times, it is normal that such objects have open and close methods, however that makes the design of the object in contradiction with Stroustrup's concept because open/close provided as methods rather than only called in the constructor/destructor means the object may be in existence yet be in a state where it is not associated with an open file. You basically have to grok that having a file object around that doesn't directly map to an open file just adds overhead to the system and is basically bad OO design in that in some sense that object is meaningless.

    Apply the same concept to a reference and you have your answer. If a reference is pointing at nothing, then what is its purpose? The only thing a NULL reference is good for is when the software design ascribes a special meaning to the value NULL. Instead of just meaning address location 0, it gets subverted to mean "variable unassigned" or the "tail node of list" or somesuch. Ascribing multiple meanings to a variable value (especially pointers/references that are only ever meant to hold memory addresses) is one example of bad programming practice known as programming by side-effect which most people agree should be avoided.

    Another point is that in most OO lanugages, references have an extra benefit of being more strongly typed than pointers, menaing that reference is guaranteed to only ever be pointing at an instantiated object of its specific type. That guarantee also gets broken when a reference can be NULL.

    1. Re:Null as a concept by read-eval-bacon-loop · · Score: 1

      I think of RIIA or however kids abbreviate it is nice concept though kind of out of place in C++. Often times it is nice to easily reserve memory for something with out having to go through the mess of having to create allocators and overload new.

      Even though I dislike most of objective C it's nice being able to separate initialization and allocation easily.

      I do use it quite frequently in other OOP languages such as java. Now if only they could add transitive and non-transitive constness--I guess I should just dust off ocaml-mode.

    2. Re:Null as a concept by swillden · · Score: 1

      I think of RIIA or however kids abbreviate it is nice concept though kind of out of place in C++. Often times it is nice to easily reserve memory for something with out having to go through the mess of having to create allocators and overload new.

      You're mixing concepts here. Although placement new syntax and STL allocators are useful, they rarely have anything to do with RAII. That is normally implemented in constructors and destructors.

      --
      Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    3. Re:Null as a concept by read-eval-bacon-loop · · Score: 1

      I probably am but conceptually the problem with RAII in C++ remains. Sometimes initializing every single thing can lead to a lot of wasted and useless work. An argument that was brought up on lambda the ultimate was arrays of some non-nullable type. In C++ you can get around it if you have a type that has a do nothing constructor. It will still be just as error prone if not more so but at least when I resize my vector to 1024 it doesn't sit there filling it in with 0.0f or some other number that will soon be replaced.

      This why RAII is a good rule to follow most of the time but in C++ especially I find I break it more often than I would like to admit.

    4. Re:Null as a concept by shutdown+-p+now · · Score: 1

      I probably am but conceptually the problem with RAII in C++ remains. Sometimes initializing every single thing can lead to a lot of wasted and useless work.

      You can separate allocation and initialization in C++ - that's precisely what placement new is for. And you can use boost.optional for a nice encapsulated class that will do all the messy details for you.

      On the other hand, this isn't something that you should do often - because a referenced allocated block of memory that isn't yet initialized as object is unsafe to treat as such, but you have no safeguards in the type system against doing so.

    5. Re:Null as a concept by Anonymous Coward · · Score: 0

      So in other words you would prefer a semantic where instead of setting an object to some invalid value, you would be able to make a call that explicitly ends the scope of the object, somewhat like destructors for dynamic objects, but applicable to static objects as well. I like it.

      (under the hood of course it may well set the variable to an invalid value anyway, but it's an error to reference the object at that point, which is enforceable at compile time)

    6. Re:Null as a concept by icepick72 · · Score: 1
    7. Re:Null as a concept by JustNiz · · Score: 1

      That sounds like a horribly messy kludge.
      Whats wrong with just using braces to scope stuff? Thats the "proper" way to do it, at least in C++.

      >> which is enforceable at compile time

      There are scenarios where that's not true, so therefore its not able to be enforced by the compiler.

      Consider the scenario where you have the call to end the scope of an object a condition of an 'if' statement that tests something only determinable at runtime.

  21. "reference to nothing" is natural by Todd+Knarr · · Score: 1

    The reason it's hard to grok null-reference-free languages is because "a reference to nothing" is a natural concept. For instance, you want to find an object in a list. What's the result when the object you want isn't in the list? A language that can't express that concept leaves the programmer scratching their head.

    The problem I run into's usually two-fold. First, programmers who don't really think about the failure case. They go looking for something, and skip the check for whether they found it. Sometimes it's just that they're lazy, sometimes it's that handling that case will be really hard, and sometimes it's because they've been told what they're looking for has to always exist so the operation can't fail. Second, compilers often treat null references/pointers as valid. Combined with the "initialize everything, always" coding style it yields nasty failures. The compiler doesn't gripe about using uninitialized variables because the variable was initialized, and neither the compiler nor the run-time gripe about using a null reference/pointer because it's considered valid. Solving those problems doesn't involve eliminating the null reference, though.

  22. The case for and against functional languages by jonaskoelker · · Score: 1

    Because forcing inherently procedural/algorithmic code into a functional paradigm makes for readable code, AMIRITE?

    Of course you're wrong; you want to be.

    Stop with the "functional languages are a panacea" bullshit already.

    They're definitely not a panacea, and I don't think anybody claimed them to be (and if they did, I don't agree with them). Your parent definitely didn't.

    What he's saying is that a particular kind of type system (let's call it the ML-like) has something that works much better than null.

    For instance, say you want to factor a number; you may want to return [2, 3, 5] for 30, [] for 1 (that is, the empty list) and some non-list thing for "error". What you can do instead of returning "list of int" is to return "either a list of int or nothing at all". But, and here's the real trick: other functions can be specified as always return a list of int without it being possible to return a non-list value, thus eliminating the possibility of "wrong" null refs.

    That's the benefit.

    1. Re:The case for and against functional languages by stdarg · · Score: 1

      Out of curiosity, how does your code distinguish between "list of int" and "nothing at all" at that point?

      I'm guessing that the simplification of the case where the function HAS to return something is made up for elsewhere with additional complexity. Clearly the function declaration is more complex because the programmer has to put in the "or nothing" part manually. Is that a whole lot different than forcing the programming to put in "assert(x != null); return x;" in the complementary set?

    2. Re:The case for and against functional languages by Sneftel · · Score: 1

      In Haskell, the more complex function declaration consists of replacing A -> B with A -> Maybe B. (It's similar in ML.) Of course you don't have to do this; the compiler will recognize from the context whether you are allowing a Nothing value or not. The complexity arises only where it must: in situations where a function makes guarantees on its outputs that are not made on its inputs.

      --
      The opinions stated herein do not necessarily represent those of anybody at all. Deal with it.
  23. Objective-C's Nil by Anonymous Coward · · Score: 0

    This is why I love programming in Obj-C. If you make a method call to a nil-valued object, nothing happens. No program crashes! Nothing! Simply no messages are sent to the object. Thus no fuss.

  24. NAP/NAR by Burrfoot · · Score: 1

    We have NAN to represent numbers that aren't. The hardware should have NAP (or NAR if they must) to represent a Pointer or Reference that is intentionally not dereferencable. The difference between this and a zero pointer would be well defined results when you 1) dereferenced, or 2) indexed based on the pointer.

    You may deposit my share of the billion of dollars saved by this idea in my Paypal account.

    1. Re:NAP/NAR by Anonymous Coward · · Score: 0

      The difference between this and a zero pointer would be well defined results when you 1) dereferenced, or 2) indexed based on the pointer.

      Well defined results, for instance, a SIGSEGV.
      Just because you don't trap it doesn't mean it isn't well defined.

    2. Re:NAP/NAR by hazydave · · Score: 1

      I wrote a version of LISP back in the early 80s that included both a NIL and an ERROR atom. Any undefined or illegal operation on valid arguments would result in the ERROR atom; subsequent operations on the error atom were all defined to not break, but also return the ERROR atom. A list of illegal operations would grow, attached to ERROR.

      This worked fairly well, since error handling could be done a useful points, it didn't have to be done everywhere. Not as powerful as true exceptions, of course, but much easier than some exception models (they weren't as well known or defined in '83 as they are today, either).

      --
      -Dave Haynie
    3. Re:NAP/NAR by mgiuca · · Score: 1

      Um, we do have NAP. It's conventionally called NULL, and much like NaN, it is up to the compiler implementor to pick a bit representation for it. Commonly, the binary value 0x00000000 is chosen.

      NULL represents a pointer or reference that is intentionally not dereferenceable.

      While the results of 1) dereferencing or 2) indexing based on the pointer are undefined in C, but in almost all modern implementations, will always result in a "Segmentation Fault" or other easily-recognisable error.

      What is a zero pointer and why do I need one? If I program malloc to never allocate the memory cell at 0x00000000 (which almost all modern implementations do), then I never need a zero pointer and I never need to worry about distinguishing NULL from zero.

      I think you missed the whole point of the discussion, which is that it's desirable to have languages with references which CANNOT possibly be null, to avoid someone passing NULL to a function which wasn't expecting it (thereby eliminating a particular class of runtime error). This has nothing to do with the overloaded representation in hardware of NULL and 0.

  25. come on now...grok? by Anonymous Coward · · Score: 0

    first of all, stop using all forms of "grok" and revert back to plain English terminology....

  26. Wrong - wrongly using valid pointers causes most by Anonymous Coward · · Score: 1, Insightful

    If what Windows Update sends me on Patch Tuesday is any judge null pointer dereferences are actually quite rare. Almost all appear to be buffer overflows and things like that (such as accidentally overwriting your stackframe - oops) and as such are caused by erroneously using a perfectly valid pointer. So the lack of range checking, and would, I guess, include the effects null-terminated strings, would probably be the most expensive. I think the reason null pointer issues are rarer is because these usually indicate a predictable fail state which is checked for. You usually only get them when you know that you not only can get them, but that you must necessarily check for them because there would be no other way to implement your algorithm. End of a linked list, for example. A map from which you retrieve items that you might not have put in there is another one. Oh, and of course I don't think all the blame can fall on the language designer even if he were really the cause behind the problem (as is highly debatable in this case) because the programmers implemented their programs, they thought they had enough prowess to use the language, and if they didn't they should have used something else. If you're drunk, you shouldn't be using a chainsaw, and the manufacturer can't be blamed if you saw your leg off.

  27. Blame LISP!! by hazydave · · Score: 1

    While Tony Hoare may not have lifted NULL from LISP, LISP 1.5 had its own version, NIL, in 1960 or thereabouts... NIL was even represented as 0, internally, at least in early versions of LISP.

    While less likely to cause problems than in a language like Algol or C, I do believe this is the earliest use of "null" in a programming language (at least until some cheeky joker out there finds an earlier one I didn't know about).

    --
    -Dave Haynie
    1. Re:Blame LISP!! by Anonymous Coward · · Score: 0

      Huh? Are you really trying to suggest that there was a time when

      (EQ NIL 0) => T

      ??

      cf. early Lisp dialects where

      (EQ NIL '()) => T

      because then what would

      (CONS 0 NIL)

      give you?

      Hint: it SHOULD be '(0)

  28. Why null-terminated strings suck so bad by mcrbids · · Score: 1

    Perhaps you should read this article written years ago that explains it very nicely.

    It's true. Null terminated strings are slow, and they suck in lots of ways.

    --
    I have no problem with your religion until you decide it's reason to deprive others of the truth.
  29. Not every computer is a desktop by wiredog · · Score: 1

    or even a handheld. For those you use a language that implements a string type that doesn't use a string terminator.

    Embedded systems are different. Much more constrained.

  30. don't forget the other one by Anonymous Coward · · Score: 0

    null. and void.

  31. Java has the right idea by Anonymous Coward · · Score: 0

    Java is a null reference-free language, sort of. Every function in Java just throws a NullArgumentException or whatever they call it, and it's just like you threw an exception instead of returning null.

    Right?

    1. Re:Java has the right idea by owlstead · · Score: 1

      There is a now dormant JSR-305 that tries to eliminate even those kind of exceptions. They are using annotation (meta-data) to avoid the use of null values as parameters etc.. Maybe there are just too few people that know about it, or you need just too much meta-data for it to be effective. It includes a smart compiler that sees if you are using (e.g.) an if statement to check for the null value; if this is the case then null is allowed. It also provide for tags to indicate immutability, and much much more.

      I think it is very weird that this JSR-305 is dormant. Even so, it is certainly interesting for those people trying to design more secure languages (a thing that is sorely needed IMHO). You can still try it out on your machine, there is an implementation available.

  32. Re:Null is NOT just a value by Anonymous Coward · · Score: 0

    That's actually a problem. Null is a piece of data that represents the absence of data. The paradox here should be obvious. If the data doesn't exist, why do we create data about it not existing?

    NULL is probably the neatest basic advance in math since the invention of ZERO. Most people don't understand the difference- ZERO means you don't have any of something, but you still have a value, i.e. knowledge that you don't have any. NULL represents that you don't necessarily even have the knowledge, i.e. there isn't even a value.

    In standard math a NULL situation simply breaks an equation or formula because computation cannot proceed, or exists as a form of a workaround where multiple formulas must be used depending on the data you have.
    The use of NULL should really be integrated into standard math.

    The idea of NULL is brilliant, especially when dealing with computer systems where you not only have to refer to data with numbers, but need to also refer to the lack of data with numbers.

  33. You can't have a non-null language by Joce640k · · Score: 1

    Not all references can be valid all the time. There has to be a way to check if a reference is valid or not and NULL is as good a way as any.

    The debate should be about:

    a) Whether dereferencing null bombs or throws an exception.

    b) Whether a language should have dangling pointers (ie. invalid but non-null).

    --
    No sig today...
  34. Re:Null is NOT just a value by microTodd · · Score: 1

    Null is a piece of data that represents the absence of data. The paradox here should be obvious. If the data doesn't exist, why do we create data about it not existing? If I have no apples, do I have an object that represents my lack of apples? No, I simply have no apples. At best, I might have a special container for apples. If it's empty, then I can infer that I have no apples.

    I've always thought of it a little differently, but then again maybe that's a Java background. I have a bunch of named cardboard boxes, and a paper list with the names of the boxes written on it.

    If the box on the list exists and has something in it, then the pointer is not null and the referenced thingy has a value.

    If the box on the list exists and is empty, then the pointer is not null and the referenced thingy has no value.

    If the box on the list does not exist, then the pointer is null.

    This, for me, was very useful in XML parsing. A zero-length string means an element "foo" exists as thus: <foo/> A NULL reference means that the element does not exist at all in the XML fragment.

    --
    "You cannot find out which view is the right one by science in the ordinary sense." - C.S. Lewis on Intelligent Design
  35. Another good thing Java threw away by michaelmalak · · Score: 1

    C/C++ always allowed a way to get around at least some NULL references: the lifetime instantiation of contained structs/objects. UML even came up with notation to distinguish between these two types of associations (aggregation vs. composition). Java threw composition to the wind, making everything a pointer (or "reference" in Java parlance), thus creating the potential for even more NULL pointer. Microsoft learned from Java's mistake and preserved "value objects" in C#.

    1. Re:Another good thing Java threw away by Joutsa · · Score: 1

      Java has final references. Just set one in the constructor, and it is guaranteed to never change.

      It is annoying, though, that every small member object carries its own memory allocation and garbage collection overhead.

    2. Re:Another good thing Java threw away by michaelmalak · · Score: 1

      Java's deferred initialization of final members still does not eliminate the null reference problem with respect to contained objects. It is possible to assign a null to the final variable in the constructor without causing a compiler error. That means every time that member is accessed, the programmer has to ask the question, "do I need to check for null, or can I assume by convention that deferred initialized members will never be assigned null in the constructor?"

    3. Re:Another good thing Java threw away by swilver · · Score: 1
      Just check the value in the constructor and you can safely assume in all the other code of that class that it can never be null. Ie. like this:

      public Car {
      private final Brand brand;

      public Car(Brand brand) {
      if(brand == null) {
      throw new IllegalArgumentException("Learn how to use this class");
      }

      this.brand = brand;
      }
      }

  36. Null References Don't Kill People... by EgoWumpus · · Score: 1

    That being said, the author is not really responsible for billions of dollars of mistakes, the programmers are.

    Null References Don't Kill People... Programmers Kill People.

    --

    [Ego]out

  37. Lying to the language - the real problem. by Animats · · Score: 3, Insightful

    A useful way to think about troubles in language design is to ask the question "When do you have to lie to the language?" Most of the major languages have some situations in which you have to lie to the language, and that's usually a cause of bugs.

    The classic example is C's "array = pointer" ambiguity. Consider

    int read(int fd, char* buf, size_t len);

    Think hard about "char* buf". That's not a pointer to a character. It's a pass of an array by reference. The programmer had to lie to the language because the language doesn't have a way to talk about what the programmer needed to say. That should have been

    int read(int fd, byte& buf[len], size_t len);

    Now the interface is correctly defined. The caller is passing an array of known size by reference. Notice also the distinction between "byte" and "char". C and C++ lack a "byte" type, one that indicates binary data with no interpretation attached to it. Python used to be that way too, but the problem was eventually fixed; Python 3K has "unicode", "str" (ASCII text only, 0..127, no "upper code pages"), and "bytes" (uninterpreted binary data). C and C++ are still stuck with a 1970s approach to the problem.

    The problem with NULL is related. Some functions accept NULL pointers, some don't, and many languages don't have syntax for the distinction. C doesn't; C++ has references, but due to backwards compatibility problems with C, they're not well handled. ("this", for example, should have been a reference; Strostrup admits he botched that one.) C++ supposedly disallows null references (as opposed to null pointers), but doesn't check. C++ ought to raise an exception when a null pointer is converted to a reference.

    SQL does this right. A field may or may not allow NULL, and you have to specify.

    Look for holes like this in language design. Where are you unable to say what you really meant? Those are language design faults and sources of bugs.

    1. Re:Lying to the language - the real problem. by dkf · · Score: 1

      You're mostly right in your post, but I'd like to take issue with a few specifics.

      The classic example is C's "array = pointer" ambiguity. Consider

      int read(int fd, char* buf, size_t len);

      Think hard about "char* buf". That's not a pointer to a character. It's a pass of an array by reference. The programmer had to lie to the language because the language doesn't have a way to talk about what the programmer needed to say. That should have been

      int read(int fd, byte& buf[len], size_t len);

      Now the interface is correctly defined. The caller is passing an array of known size by reference.

      With read() specifically, the pointer is not necessarily to the start of the buffer. This is an important point; one of the most important things about C is that you can do address arithmetic. Yes, this is a very sharp-edged tool, but it is so useful for performance. In particular, if you wrap things up so that you can only ever pass the start of a buffer, you end up having to perform many more allocation steps and many more copies of information. This utterly slays performance (a problem that is disappointingly common in programs written in C++, despite all the theoretical speed it has).

      Of course, what a good IO library does is to look after the details for you so that you write what you mean and it implements it efficiently using code that is highly reusable and extensively tested. But at that point you are no longer looking at passing buffers around, but rather higher-level entities. And the real goal is, indeed, to narrow the gap between what programmers are thinking about when they write code, and the code that they really write; we want there to be obviously no bugs, and not just no obvious bugs.

      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
    2. Re:Lying to the language - the real problem. by cicuz · · Score: 1

      Are you suggesting that going back to Pascal is a good idea? Fixed array-size has always been bashed up and down , and using another parameter to carry it around function calls isn't really gonna help anybody - starting with compilers..
      And btw, if that was really a char[] then you'd have a kind-of-nice '\0' at the end of the usable stuff (recently been helping my statistically SO [xkcd.com] with C programming).

    3. Re:Lying to the language - the real problem. by Animats · · Score: 1

      With read() specifically, the pointer is not necessarily to the start of the buffer.

      Right. But the answer to that is not general pointer arithmetic. It's providing syntax for array slices. In newer languages, you can write something like "tab[10:20]", if you want to talk about a piece of an array. (Even the current version of FORTRAN has array slices.) That expresses what's really meant, is cheap to implement, and is checkable if desired. Pointer arithmetic is a legacy of an era when the computers were too small to support a compiler that did strength reduction. (C pointer arithmetic is almost exactly what the hardware of a PDP-11 supports.)

  38. signed integers, zero, and null by ErkDemon · · Score: 1
    If you support zero, you also have to support null. Otherwise, a simple "one divided by zero" crashes the damned system.

    One divided by zero should yield "null", meaning, "not a valid computable number for further calculations". Truth tables should all have at least three columns, one, zero and null. Null times anything is null. The ability to use null dates would have avoided the whole millennium bug mess.

    So how do you express a null value? Well, apart from the idea of adding separate "certainty" registers, there was an obvious candidate. One of the major design screwups in modern computing was the implementation of asymmetrical integer ranges. That was stupid. Really, really, REALLY stupid. If negative values only go down to -127, then positive values should only go up to +127. That extra integer was a dangerous inconsistency, it meant that, for instance, if you were processing sixteen-bit waveform data, and the audio was clipped, and you wanted to phase-reverse a section of waveform, simply writing "data=(- data)" would crash the system. You'd have to manually check and weed out every appearance of a -32768 value, which shouldn't by rights have been allowed to exist in the first place.

    The anomaly with signed integers was that zero exists in both the positive and negative number ranges, giving you a spare value of "minus zero", to play with, and designers figured that since they didn't know what else do do with it, they'd use it to extend one side of the range by one additional value. They shouldn't have done it. That anomalous "minus zero" string value should have been reserved, and later wired into the processor logic as a representation of "null".

    If someone gives you a memory pointer, which references an address that is "null" (or which fails), the appropriate response is for the returned value to also be "null". Easy. You shouldn't have to preemptively check everything for bad values, operations on bad values should simply return "null", and the nulls should then propagate through the calculations until they get picked up by a leisurely programmer's check, which can then spot that something's gone wrong in particular calculation and react to the situation in a graceful and appropriate manner.

    One of the awful problems with computer design is that people originally wanted computers to give definite answers, and there are situations where definite numerical answers aren't just appropriate. A computer needs to occasionally be able to wail, "But I don't know!", or "This data hasn't been set!", or "This calculation has failed!". But the people who originally devised these systems and languages didn't consider that properly, and to a large extent, the perception of computer software as being often buggy and badly engineered is those people's fault.

    1. Re:signed integers, zero, and null by setagllib · · Score: 1

      Null dates wouldn't have avoided the millenium bug mess. Implementing such a beast is far more complicated than just extending the data field. You'd need to select a specific value for the data word and treat it specially everywhere it's referenced.

      In fact, virtually everything you have said is wrong in some way. Return null when reading null? No, that's just stupid. It would make it extremely difficult to find bugs where you actually did end up with a null pointer. And what if you write to it? Should it come out zeroed as well? I hope you don't seriously mean that PRIMITIVE types such as int should support a null value distinct from zero. Have you ever actually written systems code?

      --
      Sam ty sig.
    2. Re:signed integers, zero, and null by broen · · Score: 1

      Wow, yeah, thank you for that. Here are the thoughts that went through my head as I read the GP:

      1. Hmm, interesting.
      2. Wait, he's just misinformed.
      3. Oh, no that's so wrong I think he's trying to be funny.
      4. WTF? Or whoosh?

      Anyways, you definitely made me laugh, and succinctly summed up my thoughts:

      In fact, virtually everything you have said is wrong in some way.

    3. Re:signed integers, zero, and null by ErkDemon · · Score: 1
      Not misinformed. I'm aware that this isn't how modern computer systems work, and I'm aware that trying to retrofit this sort of feature now, as a fundamental feature, for general use, is probably not easy, or necessarily a good idea. If you were designing a fault-tolerant system today and wanted to leverage a lot of existing programming skills, you'd probably find it easier to retrofit "confidence" ratings as a separate register, and leave it to the poor programmers to decide how to deal with them (or indeed, whether to deal with them).

      But if you were designing a new system from scratch, where fault-tolerance was a priority and compatibility wasn't ... say, if you were engineering a distributed-processing network for a long-term space probe, where the hardware had to run for decades without failing, and where the system had to be able to work even with multiple processing nodes or datalinks knocked out by cosmic rays or high-energy dust ... then "null" values and/or confidence registers become more important. If a processing node goes haywire, you want it to be outputting nulls rather than junk data, and if you lose a few sensors, you want their contributions to be nulled, and for the certainty of the results of any calculations that would have used their data to be downgraded accordingly.
      Sure, you can use additional variables and lots of conditional tests to achieve similar results, but its safer and cleaner if you build the validation logic in at a deep level, and let it happen automatically.

      The point that I was trying to make was that the basic design concepts that our systems are based on were compromised by bad design right from the beginning. If we were designing languages and processors from scratch, we wouldn't necessarily do things the same way. But once certain conventions and decisions are sufficiently entrenched, it becomes difficult to change, even if we believe that the current system isn't optimal. Like the QUERTY keyboard -- the way that computers //currently// work isn't necessarily how they //have// to work.

  39. Re:20 second explanation - Pendantic reply by geekoid · · Score: 1

    "Because anything a NULL interacts with becomes a NULL. "

    Ummmm No.

    The results are NULL, nothing becomes NULL*.

    In your example (car) (mouse) (fox) don't become NULL, the result of the evaluation is NULL.

    * This includes divide by Zero in most larger Databases..but not all.
    Important to note because this can really mess up a complex query that you would expect to through an error but instead passes a NULL.
    Or so I heard....cough.

    Hey, it as my first profession gig, and ti was just about a billion years ago.

    --
    The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
  40. Not nerdy by hey · · Score: 1

    Sorry this thread (and the passion in it) is not nerdy enough. Could we please have some nerdy stuff on Slashdot!

  41. So fucking what? by Nicolas+MONNET · · Score: 1

    16 bit is too small in some cases? Well then rewrite the library for 32 bits.

    Seriously.

    Thing is, people rewrote the library that did not exist a thousand times anyway, and more often than not used C strings when they shouldn't have, resulting in countless disastrous buffer overflows.

    Oh and btw, there is a simple solution to this non-problem:


    #define STRING(typ) typ##string
    #define DEFINESTRING(typ) typedef struct { \
            typ len; \
            char c[0]; \
    } STRING(typ);
    DEFINESTRING(int);
    DEFINESTRING(long);
    DEFINESTRING(uint128);
    /* later */

    int println(STRING(int) a) {

    1. Re:So fucking what? by Vanders · · Score: 1

      Oh and btw, there is a simple solution to this non-problem:

      You are remote system 'X'. I am client 'Y'. I send you a string. The first eight bytes of the stream are:

      0x82 0x31 0x32 0x6A 0x7B 0x72 0x34 0x37

      Did I just send you a 16bit string, or a 32bit string? Or perhaps it's a 64bit string?

      So do we force everyone to standardise on one known protocol? Now you have the overhead of converting from your native size to the "neutral" size. What if you're a 32bit machine and the neutral size is 64bit? Well, perhaps we could use a more complex encoding scheme? Ever seen the ASN.1 spec?

    2. Re:So fucking what? by Anonymous Coward · · Score: 0

      You have to standardize on something, in any case. Using '\0' as a terminator means you can't transmit arbitrary binary data without escaping.

    3. Re:So fucking what? by Rycross · · Score: 1

      You either 1) standardize on something or 2) reformat it in the client to a format that the server understands. Sheesh, this isn't rocket science. It wouldn't be the first time a programmer has written a translation layer to convert an internal format to an external one. Hell, we had this problem with endian-ness.

      The problems of re-formatting data are trivial compared to the issues with terminated strings. There's not a perfect fool-proof way of doing it, but a length/data representation is much better than termination.

    4. Re:So fucking what? by Anonymous Coward · · Score: 0

      You sent me bytes. Without a protocol agreeing on what those bytes represent, they're meaningless. Even if I know it's NUL terminated (which means you can't ever use NUL in a value), I don't know whether it's supposed to be EBCDIC or Latin-1 or UTF-8.

  42. Null is necessary by Anonymous Coward · · Score: 0

    Null is necessary in as much as an empty set is not equivalent to having no set at all. How could you represent "no set" without null? Perhaps an empty set of sets? Possible, but that's a poor solution because the semantic isn't clear. This is a practical problem and Null is the correct solution.

  43. Hmm by pdxp · · Score: 1

    ... in Microsoft have been used to check references, and give warnings if there is a risk they may be non-null.

    Because non-null references are a no-no at Microsoft. It might lead to working code!

  44. Not even THAT is the problem by Anonymous Coward · · Score: 0

    Use it when you know what you do.

    Last time when the Debian project has tried to remove uninitialized pointers in ssh it fired back as a disaster for them and all derived distributions. They have reduced the entropy to 15 bits in their encryption routines.

  45. A pointer may be a reference. by wiredog · · Score: 1

    But a reference is not necessarily a pointer. Certainly C# and Python have pointers, but I've never needed to use them. References, yes. Pointers, no.

    1. Re:A pointer may be a reference. by Abcd1234 · · Score: 2, Insightful

      But a reference is not necessarily a pointer.

      In the context of this article, it sure as hell is. The entire point is that the concept of "NULL" can be dangerous. And pointers and references both support this concept, and are thus dangerous for the exact same reasons.

  46. Those aren't pointers by wiredog · · Score: 1

    Those are references.

  47. And Slashdot burns through the second billion $ by astrojetsonjr · · Score: 1

    *poof* there goes the second billion in cash, in the form of wasted time by Slashdot. Sorry Tony, you'll need to update the title of your presentation.

  48. warnings when non-null? by Anonymous Coward · · Score: 0

    [PREfix and PREfast] give warnings if there is a risk they may be non-null

    English is not my language, but shouldn't this be the opposite? i.e. "give warnings if there is a risk they may be null"

  49. To JonR by Anonymous Coward · · Score: 0

    You A$$H

  50. Not the only way. by Estanislao+Mart�nez · · Score: 1

    The other alternative to forced nullable types in your language is to have labeled union types, à la ML/Haskell. This feature's scope takes care of the cases where you genuinely want null, and of enumeration types in general, too.

    The Haskell type system allows you to define types that are an "or" of several named subcases. Each subcase can have values of other types as contents, or nothing. So, for example, in Haskell you can define the following type, called Maybe (I hope I get the syntax right!):

    data Maybe a = Nothing | Just a

    This is a parametric type, parametrized over a type variable, 'a'; thus you can use the Maybe type constructor to construct types like Maybe String, Maybe Integer, Maybe Tree, etc. A variable of type Maybe String can take two kinds of value:

    var1 :: Maybe String
    var1 = Just "this is a string"

    var2 :: Maybe String
    var2 = Nothing

    What this implements is the idea that a variable whose value is always an object of type t has a different type than a variable whose value is either an object of type t, or some designated, extra value that means "nothing." Then you code can be written so that contexts where it doesn't make sense to have nulls make use of the plain types, contexts that really require nullable types use those, and that to go from a nullable context to a non-nullable one you need to perform some sort of type cast that checks and handles the null case.

    This falls out for free from labeled union types, but it would be very easy to get a limited version of this in a language without labeled unions, by nullability as a sort of type annotation, and defaulting all type declarations to not nullable. In this model, a variable cannot be null unless you've declared it to be nullable, and whenever you need to pass a value held in a nullable variable to a function whose arguments aren't nullable, you'd need to convert the variable's value to a non-nullable type, which would perform a null check. You'd have a compilation-time guarantee that the only places in your program where nulls can occur is those places where you've declared they can.

    1. Re:Not the only way. by Anonymous Coward · · Score: 0

      I always wondered why nofucker in the real world uses Haskell. One is what you said. The other is you.

  51. maybe type by j1m+5n0w · · Score: 4, Informative

    Maybe types are wonderful. I first thought they were inconvenient, since you have to pattern match against them any time you want to extract the value, but then I realized that that was something I ought to be doing anyways, and the advantages of never accidentally dereferencing a null pointer vastly outweigh a little extra typing. And then, more recently, I figured out how to use the maybe monad to string together a bunch of things that might fail without having to manually pattern match every time.

  52. "core constants" were around at least by 1960s by Ungrounded+Lightning · · Score: 2, Interesting

    The first OS I encountered was tape-based. And it prefilled user memory with a "core constant".

    This was a subroutine jump to an abort routine which printed the return location - which in turn told you where you had improperly jumped to and dumped all your registers, followed by the memory itself if that was authorized. (That was all the info that was left by the time the OS got control.)

    The walls of the computing center contained posters giving this value as it would appear if printed as various types of values (integer, floating point, complex, ...).

    Another machine I dealt with back then was a typesetting device using a Data General Nova and the company's homebrew OS (designed by Mark Weiser of Xerox Parc fame, based on work by Djikstra and Riddle). It had a debugger entry that could be reached by a one-word instruction which we would insert as breakpoints and also use to fill unused memory. The hex form of this was "0c0f". When the machine hit a breakpoint we said it had "coughed".

    --
    Bantam Dominique roosters crow a four-note song. Once you've heard it as "Happy BIRTHday" you can't NOT hear it that way
  53. One null reference isn't so bad by Locke2005 · · Score: 1

    What bothers me is systems like MS Access, which effectively have 3 different types of null, each of which must be tested for separately. Now that is a billion-dollar design mistake!

    --
    I've abandoned my search for truth; now I'm just looking for some useful delusions.
  54. "No Such Thing as a Null Pointer" by sinclair44 · · Score: 1

    Our programming languages professor, Robert Harper, recently talked about this concept in class. Although he argued that there was "no such thing" as a null pointer, what he actually meant to say was either there shouldn't be such a thing, or that a properly designed language would not have such a notion.

    Consider SML (which, incidentally, he helped design). There are of course basic types, ints and bools etc, but it also has the notion of an "option" datatype. A foo option can either be NONE, or SOME of foo. For example, if you are doing some calculation that returns an int but may somehow fail to calculate its result, it will return an int option, with either SOME(result) if there was success, or NONE if it failed. Due to SML's strong type system, the function using that result would have to do case analysis on the result -- you can't use an int option as if it were an int; you need to pattern match and grab the int out of the SOME case and otherwise handle the NONE case.

    Java (and C and...) doesn't do this properly. Take an ArrayList, for example. When you say "ArrayList foo", what you actually have is an ArrayList option, he argued, since you really either have SOME(an actual ArrayList) or NONE, representing the null pointer. Except Java has no notion of option types. There's no way to actually get an ArrayList -- you always have an ArrayList option. You have to check for NULL every time.

    Thus his argument for why Java et al are badly designed, and how you can properly design a programming language without a need for a NULL pointer -- you use a different type altogether, upon which you can properly case analyze.

    --
    Omnes stulti sunt.
    1. Re:"No Such Thing as a Null Pointer" by Fulcrum+of+Evil · · Score: 1

      Although he argued that there was "no such thing" as a null pointer, what he actually meant to say was either there shouldn't be such a thing, or that a properly designed language would not have such a notion.

      Wow, a classic example of begging the question - you can't counter by example because every language with a null pointer is by definition improperly designed. What it comes down to is "I don't like null".

      Consider SML [wikipedia.org] (which, incidentally, he helped design).

      Then consider Lisp, which has the concept of null and case analysis, and has the additional advantage of not being supremely painful to use.

      Java (and C and...) doesn't do this properly. Take an ArrayList, for example. When you say "ArrayList foo", what you actually have is an ArrayList option, he argued, since you really either have SOME(an actual ArrayList) or NONE, representing the null pointer.

      No, Java chooses a faster, implicit, option type - it's the same thing, just not explicitly stated. The only difference here is that the language doesn't make you check for null. C is portable assembler, so you shouldn't expect much.

      --
      "We returned the General to El Salvador, or maybe Guatemala, it's difficult to tell from 10,000 feet"
    2. Re:"No Such Thing as a Null Pointer" by Estanislao+Mart�nez · · Score: 1

      No, Java chooses a faster, implicit, option type - it's the same thing, just not explicitly stated. The only difference here is that the language doesn't make you check for null.

      Um, there is zero reason why implicit option types would be any faster than the equivalent base types. Option types can be trivially implemented as compilation time type checking, with implicit nullity checks when you cast an option type to its base type. The physical representation of the data and the generated object code could be exactly the same; the only difference is that when you use the base types, the compiler proved at compilation time that certain expressions never evaluate to null.

      Hell, I wouldn't be surprised in fact if there were optimizations that are made impossible by having every type implicitly be an option type. Basically, it makes you unable to optimize away situations where the existing runtime system needs to check whether a reference is null. (It's a cheap check, yes, so it might not make a difference in practice, but as a general rule, stronger type system = more optimizations available.)

    3. Re:"No Such Thing as a Null Pointer" by Fulcrum+of+Evil · · Score: 1

      Option types can be trivially implemented as compilation time type checking, with implicit nullity checks when you cast an option type to its base type.

      You still have to check at runtime - you can still get null references where none should exist

      Basically, it makes you unable to optimize away situations where the existing runtime system needs to check whether a reference is null.

      Why would you ever do that? Null checks are cheap and the idea of a compiler removing mine scares me.

      --
      "We returned the General to El Salvador, or maybe Guatemala, it's difficult to tell from 10,000 feet"
    4. Re:"No Such Thing as a Null Pointer" by Estanislao+Mart�nez · · Score: 1

      You still have to check at runtime - you can still get null references where none should exist

      Yes, you have to check at runtime, but the places where you do have to check are restricted: only places where you convert from nullable to non-nullable. This means that null pointer exceptions are thrown closer to where the nulls originate, instead of having the current situation, where a null erroneously generated in one place in the code can propagate through thousands of lines all over the place before it lands somewhere where a null is really not tolerated.

    5. Re:"No Such Thing as a Null Pointer" by Estanislao+Mart�nez · · Score: 1

      Null checks are cheap and the idea of a compiler removing mine scares me.

      Null checks are cheap indeed, but there are still bound to be places where removing them can be a useful optimization. I've thought harder about it, and the one sort of case where I think it might be valuable is when inlining code into inner loops.

      I don't think you should be any more scared of the compiler removing such checks than you are of compiler optimizations in general. In theory, the compiler can remove checks or alter the way they are done if it can prove the program won't be affected. In practice, actual compilers certainly do have optimization bugs (check out this bug in Java). My point? You should be as scared of of your compiler removing null checks about the same amount as you are scared of compiler bugs already. (And IIRC, Java already does null-check elimination.)

  55. Too pervasive by shutdown+-p+now · · Score: 2, Informative

    The problem with NULL/null/None as implemented in C++/Java/C#/Python/whatever is that it's pervasive - it always "adds itself" to the list of valid values of any reference type (= pointer type in C++, = any type in Python), in all contexts. At the same time, it isn't truly a valid value, because you can't do with it what you can normally do with any other value of the type. It's actually a lot like signalling NaN for object references, and is an equally bad idea for the same reasons.

    How to handle that? Why, with explicit "nullability markers", and languages which track nullability propagation, and require to check for null everywhere you try to perform an operation that won't work for a null value whenever you have a value that can potentially be null. In FP languages, this is naturally done with ADTs; for example:

    (* Standard library *)
      type 'a option = None | Some of 'a;;
     
      (* User code *)
      let foo (xo : int option) =
        match xo with
        | Some x -> ...
        | None -> ...

    Note that OCaml compiler, in the example above, won't let you omit the "None" branch. You have to handle that (well, you can just pass on the "int option" value, but only to another function that is declared as taking one, and not just "int"). Also note how the other branch is guaranteed to get some specific, "non-null" int value for x.

    These enforced checks prevent silent null propagation, which is the bane of Java, C#, and other languages in the same league. All too often some code somewhere gets a null value where it shouldn't, stores it somewhere without checking for null, and then another piece of code down the line extracts that value (which is not supposed to be null!), passes it around to methods (which pass it to more methods, etc), and eventually crashes with a NullReferenceException - good luck trying to track down the original point of error!

    1. Re:Too pervasive by bjourne · · Score: 1

      That is a great explanation of why NULL is bad.However, note that in imperative languages, NULL can almost always be eliminated. For example, an OCaml function for finding an item in a list could return a string option. In an imperative language, you would throw an exception instead of returning anything at all. For default values, you can use NullObjects. Unfortunately, most programmers does not practice proper "null avoidance" which is why problems with null are so pervasive.

    2. Re:Too pervasive by shutdown+-p+now · · Score: 1

      That is a great explanation of why NULL is bad.However, note that in imperative languages, NULL can almost always be eliminated. For example, an OCaml function for finding an item in a list could return a string option. In an imperative language, you would throw an exception instead of returning anything at all. For default values, you can use NullObjects.

      It's not so easy, unfortunately. The problem with imperative languages specifically is, what to do with default initialization rules? Right now Java default-initializes all fields of a new object to null, and also all elements of a newly allocated array. You can require explicit initialization for fields, sure - take C++ semantics and make them more strict - but what about arrays? A functional approach would be to require an initializer for the array as well, for example, in the form of index-to-value mapping function that would provide some specific value for every element. Good, now try to implement, say, a generic Java-style ArrayList on top of such an array - keep in mind that you have to pre-allocate extra space for new elements in advance, and, since there is no "null", you don't have any reasonable default value for an arbitrary generic type parameter T for those pre-allocated slots. So, it's not all that simple.

      Of course, you can still provide a "magic" implementation of ArrayList in the standard library that is implemented in an unspecified, implementation-defined, unsafe-but-proven-correct way, and expose only the API for that. But that's not "neat".

      This was actually covered on LtU not long ago, in a post about the very same article.

    3. Re:Too pervasive by Nazlfrag · · Score: 1

      enum completeBit {0, 1, NULL, NaN, FILE_NOT_FOUND, RESERVED};

  56. Haskell's null-free behavior by ijones · · Score: 2, Informative

    I can illustrate the concept of a null-free language with examples from Haskell.

    With Haskell types, you can specify all the valid values of a particular bounded type (the same is true for non-bounded types, but its more obvious for bounded ones):

    data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday

    Something of type "Day" cannot be NULL. It must be one of the days of the week. It's impossible to construct a value of a "Day" type without "assigning" it one of these values.

    But then what if you want to handle a case where it might be none of these? There's another type for that called "Maybe", and you can wrap "Day" (or any type) in "Maybe" to indicate that it might be none of these. So "Just Monday" is a value simultaneously indicating non-null, and providing the Day value. "Nothing" indicates NULL or "none of the above".

    For instance, if you write a function which gives the next day of the week, given a day of the week, it should input Day and output Day. It doesn't make sense for either its input or its output to be NULL. That is, it should have type "Day -> Day".

    But if you want to handle for instance, a case of user input or parsing, where they might not give a valid day, then you should use the type "Maybe Day" or something similar.

    Values of "Nothing" in Haskell roughly correspond to NULL except that the type system differentiates cases where something might be NULL and cases where something promises not to be NULL.

    This turns out to be a useful distinction :)

    peace,

        isaac

  57. Re:Null is NOT just a value by AKAImBatman · · Score: 1

    If the box on the list does not exist, then the pointer is null.

    Actually, the slot doesn't exist. The "null" you're thinking of is merely an artifact of the language.

    This, for me, was very useful in XML parsing. A zero-length string means an element "foo" exists as thus: A NULL reference means that the element does not exist at all in the XML fragment.

    A NULL reference shouldn't exist. There should simply be no reference. i.e. If I see this:

    <myxml><foo/></myxml>

    It might parse to this:

    ArrayList
        [0]Foo

    But if I have this:

    <myxml/>

    It should parse to an empty list like this:

    ArrayList

    But what if you only ever expect one instance of Foo? Might you do this?

    class MyXML
    {
        public Foo foo;
    }

    You could, but this would be a denormalization of the data. None the less, it is a situation that needs to be handled. In an ideal world, the "foo" member wouldn't exist until it is assigned a value. (See Javascript for a language that works this way.) Thus you would need to test for the existence of "foo" rather than checking "if(myxml.foo == null)".

  58. Re:Null is NOT just a value by Anonymous Coward · · Score: 0

    If I have no apples, do I have an object that represents my lack of apples? No, I simply have no apples.

    Clearly you need to take your common sense particle. Then you could have both.

  59. Great explanation by __aawkdb2598 · · Score: 1

    Very good! I like this explanation. No mod points today, unfortunately :(

  60. no such requirement at the assembly level by r00t · · Score: 2, Insightful

    The compiler can do anything it damn well pleases, as long as the end result acts like it should.

    The compiler certainly can dereference the pointer. It can also throw in a call to sin(42), a write to some memory containing the current line of code, and a system call to check for pending debugger stuff.

    None of this would make the high-level view of things be anything other than the required short-circuit evaluation of the given code.

    1. Re:no such requirement at the assembly level by thethibs · · Score: 3, Insightful

      You are confusing C with...well, I'm not sure what...Haskell, maybe? In many cases with C, the sequence of events is as important as the end result. C code can have side-effects.

      C is not an expression evaluator, it's a control language; A && B is an instruction to copy A and if it is non-zero, replace the copy with B, in that order. A++ says copy A and then increment it.

      Most of the people on slashdot can tell you why that's important and a few of them have; there are more than a few scenarios where not getting the sequence right would have undesirable effects even if the returned value was correct. Look up memory-mapped I/O.

      --
      I'm a Programmer. That's one level above Software Engineer and one level below Engineer.
    2. Re:no such requirement at the assembly level by amorsen · · Score: 1

      You can't do memory mapped I/O in standard C. You can't even do threads in standard C (well you can, but only if you don't try to share state between the threads, and then what is the point...)

      Everyone does it anyway, and the compiler people mostly learned to not be too strict about this. One nasty exception is strict aliasing, which breaks a lot of real-world code.

      --
      Finally! A year of moderation! Ready for 2019?
    3. Re:no such requirement at the assembly level by thethibs · · Score: 1

      If you can't do memory-mapped I/O or threads in standard C, then the standard has drifted too far from the original intent which included "If you can do it in assembler, you can do it in C."

      I guess I should hang on to my old copy of bcc, just in case.

      --
      I'm a Programmer. That's one level above Software Engineer and one level below Engineer.
    4. Re:no such requirement at the assembly level by russotto · · Score: 2, Informative

      You are confusing C with...well, I'm not sure what...Haskell, maybe? In many cases with C, the sequence of events is as important as the end result. C code can have side-effects.

      The optimizer wouldn't do it unless there were no side effects to the right hand side of the short circuit operator.
      So

      if (foo && (*foo == CONSTANT))
      and
      if (!foo || (*foo == CONSTANT))

      would be optimized in this way
      but

      if (foo && baz(*foo))

      would not (since function baz could have side effects).

      It doesn't matter what was at location 0; the test for null was still evaluated, but condition code arithmetic rather than branches were used to handle it.

    5. Re:no such requirement at the assembly level by russotto · · Score: 1

      You can't do memory mapped I/O in standard C. You can't even do threads in standard C (well you can, but only if you don't try to share state between the threads, and then what is the point...)

      Um, "volatile" keyword?

    6. Re:no such requirement at the assembly level by iluvcapra · · Score: 2, Insightful

      Volatile keyword often works, since this hint the compiler to always get/set the value on core instead of trying to keep it on a register where other threads couldn't see it, but by the standard, "What constitutes an access to an object that has volatile-qualified type is implementation-defined." ( 3.5.3) and that's not guaranteed.

      --
      Don't blame me, I voted for Baltar.
    7. Re:no such requirement at the assembly level by Anonymous Coward · · Score: 0, Funny

      Yes, because Haskell doesn't operate on values or computer registers internally. It works entirely on pixie dust and unicorn tears.

      Stop the crap please. It is okay if you like the language or it fills your belly, but don't feel the need to advertise it at any unlikely opportunity. You are not welcome.

      You Haskellers are like furries or homosexuals, always needing to advertise your deviation to normal people.

      You can write side-effects-less C code just as easily as you can in Haskell. That you can do something about side effects when it makes sense instead of just abstracting them away entirely is the defining power of C.

    8. Re:no such requirement at the assembly level by Anonymous Coward · · Score: 0

      He is not confusing anything.

      Bare C does not support memory-mapped I/O.

      It can be done with most implementations do, but only provided you enhance them by solving dirty details like memory ordering, which imply assembly language, so by default you should better consider that no bare general purpose C implementation support memory-mapped I/O (at least without on purpose extensions) or you will write nasty bugs. It can happen that sometimes the compiler helps you by not doing certain kind of optimizations that would annoy you if you are writing some low level code, but this is not something the spec gives you.

      Once again as long as the compiler is sure that it will preserve appearance of what the standard says, it is allowed to do anything it wants. And the standard does not say what should happen on the bus when you access to something that is in memory. The standard also don't say anything about speculative execution by modern microprocessors, and believing the C language guarantee you anything about what happen on the bus is just completely foolish in this context...

    9. Re:no such requirement at the assembly level by Anonymous Coward · · Score: 0

      Oh my god, you have been betrayed by the evil norm writers!

    10. Re:no such requirement at the assembly level by fractoid · · Score: 1

      You Haskellers are like furries or homosexuals, always needing to advertise your deviation to normal people.

      Having been forced to ingest a greasy lump of Gopher as a first-year student, this made me laugh hard enough to make it my first new /. sig in years.

      --
      Rampant carbon sequestration destroyed the Dinosaurs' tropical paradise. I'm here to help repair the damage.
    11. Re:no such requirement at the assembly level by amorsen · · Score: 1

      volatile helps you when you have to share data across longjmp. That's the only thing the standard guarantees you can use it for.

      --
      Finally! A year of moderation! Ready for 2019?
    12. Re:no such requirement at the assembly level by againjj · · Score: 1

      Actually, as long as the high-level semantics are preserved, the compiler does not have to short circuit the evaluation. If the compiler can figure out that A && B is exactly equivalent to (including any potential side effects) ((bool)A) & ((bool)B) then the compiler is free to make that replacement and avoid the costly branch. The standard dictates behavior, not implementation. Should a pointer dereference have no adverse effects, the compiler is free to do that, as well as through in a call to sin(42).

  61. that constant is known to the compiler by r00t · · Score: 2, Informative

    The compiler depends on the OS to set up certain things, including the memory at address 0.

    If I remember right, *(int)0==0 on this system.

    It's totally legit. The C standard says nothing about how the assembly code behaves, or even that there is any assembly code. (C can be an interpreted language)

  62. SQL uses three-values logic. by Estanislao+Mart�nez · · Score: 1

    If x is NULL, the statement [x > 0 OR x

    No, it isn't false. SQL is based on a three-valued logic, not on boolean logic, and comparisons involving NULL evaluate to the third truth value, commonly notated as unk (for "unknown"). This is treated equivalently to false in most contexts, but is treated the same way as true in check constraints. Read up.

  63. how it works by r00t · · Score: 2, Insightful

    We do "if (foo && *foo == CONSTANT)" like so...

    The programmer wants to access *foo, unless it is NULL. We will thus do so. Additionally, we know that *NULL will not fault (on the AIX operating system) and that it will give us a zero. Thus, we can access *foo in any case.

    The code becomes:

    tmp=*foo; if(foo && tmp==CONSTANT)

    The C standard only places requirements on an abstract machine. Underneath it all, the code could be getting executed by a bunch of monks who chisel computations into blocks of granite. It doesn't matter if one of the monks takes a bathroom break or whatever. The C standard doesn't care.

    1. Re:how it works by Anonymous Coward · · Score: 0

      The C standard only places requirements on an abstract machine. Underneath it all, the code could be getting executed by a bunch of monks who chisel computations into blocks of granite. It doesn't matter if one of the monks takes a bathroom break or whatever. The C standard doesn't care.

      And what you're ignoring is that the C standard says that, given the code:

      if (ptr!=NULL && *ptr!=0xDEADBEEF) { ... }

      the abstract machine Shall Not Dereference That Pointer if it is equal to NULL. The designers of C decided that short circuit logical expression evaluation was such a cool thing that they wrote it into the language as a requirement. C guarantees left-to-right evaluation of its logical AND and OR operators (&&, ||) and guarantees short-circuit behavior, meaning that as soon as it's possible to know the outcome of the whole expression, left-to-right evaluation stops.

      There are no special exceptions:

      Additionally, we know that *NULL will not fault (on the AIX operating system) and that it will give us a zero. Thus, we can access *foo in any case.

      The C standard says NOTHING about page faults. It's very deliberately written to address the machine at a more abstract level than that. And the abstract machine defined by C does not evaluate the right hand argument of the && operator whenever the left hand argument evaluates to false. Period. End of discussion. There are no special exceptions if the left hand side happens to be a check for a NULL pointer and the right happens to be a dereference of the same pointer.

      Is it possible for somebody to write a compiler which does check for that specific scenario and introduce an optimization relying on early evaluation of the right hand side? Sure. Will it introduce bugs? Probably not. But don't claim that it's a conforming compiler, because it isn't.

    2. Re:how it works by Anonymous Coward · · Score: 0

      the abstract machine Shall Not Dereference That Pointer if it is equal to NULL

      ...and it doesn't, so we're OK. You're confusing the abstract machine with the real machine.

      Abstract machine: must be short-circuit

      Real machine underneath: may do anything

  64. Re:Null is NOT just a value by stdarg · · Score: 1

    In an ideal world, the "foo" member wouldn't exist until it is assigned a value. (See Javascript for a language that works this way.) Thus you would need to test for the existence of "foo" rather than checking "if(myxml.foo == null)".

    What have you gained by substituting one test for another?

  65. Re:Null is NOT just a value by AKAImBatman · · Score: 1

    The theory of type checking is that the sooner an error is caught, the less likely it is to cause damage. Thus if null does not exist, errors will occur as soon as the non-existent reference is used. This is in direct opposition to a null value where the null can be passed all over the place before it triggers an error. Potentially, incorrect processing may even be done with the null value in the mix.

    In addition, code analysis can be done on reference checks. If the compiler knows that a member is undefined when you attempt to access it, it can throw an error if it's unguarded. Similar to this situation:

    Object myobj;
     
    myobj.blah();

    The compiler will complain very loudly about myobj being uninitialized. Member variables don't currently have this protection because they default initialize to "null".

  66. The real McCoy ...er, Hatfield (Re:null or not) by Anonymous Coward · · Score: 0

    SearchTerms: opcode C4C4 bop "jim hatfield"

    0xC4C4 is an invalid instruction, generates interrupt 6. For one operating system this interrupt is handled by KiTrap06 where C4C4 can be recognized as a BOP and possibley handed to NTVDM.EXE.

  67. hex words... by CBravo · · Score: 1
    --
    nosig today
  68. Re:20 second explanation from idiot End Of Days by Anonymous Coward · · Score: 0

    Coming from the picture of ignorance himself on the internet in End of Days (slashdot's ultimate douchebag).

    Go spout your never done this kind of work youself blabberings to yourself because they usually totally lack any technical content whatsoever and most certainly that from you yourself without citing somebody who does know what they are doing which anyone can do. You are technically challenged in this science as well as mentally challenged obviously and the fact that you just do not have the means in this science to do so yourself.

    To this reply he'll post as ac next because he was caught in that much this week here already. Talk about stupid and thank goodness End of Days the moron is stupid enough to be a registered user here chasing useless karma points which makes him ridiculously simple to track because of it.

    End of Days because you like to screw with others the return screwing is not going to stop being directed your way just to teach you a lesson you dumb shit little not man (more like the deceitful little typical nerdy wanna be bitch you are) and there's not a thing you can do about it. Time to put the other shoe on your foot and laugh at you while doing so, so you can see how it feels. Come on helpless wanna be. Try to stop me. You're not intelligent enough to do so.

    I can't wait to see his ac reply too like usual. Who is the idiot End of Days think he is fooling in trying to do that?

  69. Haskell = no Null references by Hurricane78 · · Score: 1

    I am very happy that I managed to completely ship around having to program in C/C++. And mostly for that horrible pointer and variable mess that it resembles. Try crashing your Haskell program that way. It will only work if you supply it with data via the foreign function interface, from... you guessed it: C.

    I think we should brush Haskell a bit up so it plays nice with direct hardware access (interrupts, registers, and so on), optimize its compiler a bit more, and replace C by it.
    Of course this will not happen in the next 10 years. But luckily, I can program in whatever I want, and even re-implement software in Haskell, if I absolutely have to.

    --
    Any sufficiently advanced intelligence is indistinguishable from stupidity.
    1. Re:Haskell = no Null references by JustNiz · · Score: 1

      Haskell/Java/VB etc are like plastic scissors.
      C and C++ are like a scalpel.

      Plastic scissors are great for kids, but there's a good reason that surgeons use scalpels.

  70. Re:Null is NOT just a value by microTodd · · Score: 1

    That's a neat idea. It kind of blew my mind for a second. Members that don't even exist. I see what you mean by this being a paradox. Not sure how this could be addressed in the typical "C-family" of compiled languages. Maybe in some other programming paradigm. Seems like Perl does stuff like this, being able to dynamically modify the structure of classes and objects at runtime. One one hand you fall back on the crutch of doing the same type of existence checking with "if defined()" instead of "if NULL", but on the other hand if you are using iterators then it falls neatly into place.

    --
    "You cannot find out which view is the right one by science in the ordinary sense." - C.S. Lewis on Intelligent Design
  71. 0xdeadbeef could be a vaild address by frog_strat · · Score: 1

    But with modern memory management, I suppose it would be no more difficult to have the memory manager set aside that page as invalid, as it does with page zero.

  72. Re:20 second explanation from idiot End Of Days by The+End+Of+Days · · Score: 1

    Yeah, chasing karma, that's me.

    I don't need to bother. I have more accounts than you'll ever realize.

  73. Great analogy, faulty reasoning by maharvey · · Score: 1

    Your hand is always full. If you don't have an apple, you may have an orange. If you don't have an orange, you might have any of a million other things. When your hand contains air, we say it is empty, even though it is not. Emptiness is only an abstraction, and it is assigned to a specific content.

    NULL is the air in your hand.

    1. Re:Great analogy, faulty reasoning by AKAImBatman · · Score: 1

      When your hand contains air, we say it is empty, even though it is not.

      Replace my hand with a robotic arm in space. Claw is open. What exists in the claw?

      Emptiness is only an abstraction, and it is assigned to a specific content.

      Technically, all high level code is an abstraction. As is mechanical work in the universe. Both are caused by complex quantum interactions at very low levels. The purpose of the abstractions around both is to produce a framework that is as easy as possible for the human brain to grasp and work with. Situations like NULL values are a form of leaky abstraction that are very confusing and don't map to concepts that are intuitive for humans.

      The catch is that once we learn and intuitively use the abstraction, it becomes difficult to think without the abstraction.

  74. Re:20 second explanation from idiot End Of Days by Anonymous Coward · · Score: 0

    There you are. End of Days admits to doing replies under multiple usernames here as well as ac to make it appear that he has the backing of others in order to attempt to do so as well and now being caught in it via his own admission of his modus operandi. You are too easy to out think and You only show you are a bitch because you practice that which bitch not men do. How can limp whimps like you even face women when you are women yourselves in being not men? Your continued stupidity continues to manifest itself here and helps prove the points others state about you. I have to thank you for being so stupid and so easy to flush out here as well as showing us all how easily you fold under pressure once someone pushes the right buttons in your limited brain but most of all for the fact you are the only woman on the planet with a penis because how you act and go about things online is not what men do. At least not real men. An ac can do the same easily but then again you are too stupid to know how that is done to beat the ac account limitations. Your kind, worms, do this online because they think there are no repercussions. Well there is now because this account which is only 1 of multiple you admit to using here? Give up on it. I am going to take it from you as will others because your reply here is being rightfully put down because of your skimming and lack of know how in this science. I can see you when you were younger lol when other guys were porking your girlfriend and making you do their yard work and you have not changed at all. Here online your kind thinks they can't get caught but you can and have easily because you are stupid. You make real nerds that know what they are about look bad and they probably don't like your kind either. Have all the fake or multiple accounts you want because I'll just bgp find you again easily if you continue this crap. You can only blame yourself as you only brought this on yourself and deserve every second of it. Think twice before bothering us here with your crap again under your other accounts because it is not a load of work to determine who and where you are on this forums. Until then I will just point everyone to this admission of yours under this account so they can see the real you and ridicule you, not man. Every post you make from now on under this account will point to this admission of yours of using multiple accounts here and ac also to make it seem others agree with your massive crap? This time you grabbed a tiger by its tail and I'm going to take it away from you and you will give up this account because of it out of shame little bitch but that assumes little bitch not men like you even have pride and your kind doesnt as there isnt anything to be proud of. Thanks for being so stupid and admitting to how a not man like you really operates and how low you are. Dont wonder why women wont give you the time of day because youre more of a woman than they are.

  75. Um, what? by Estanislao+Mart�nez · · Score: 1

    From the perspective of comp-sci, is that a correct solution? The answer is "no". An absence of data should simply be an absence of data, not a piece of data that represents the absence of data.

    How is that "the perspective of comp-sci"? And more importantly: what the hell is that supposed to mean in the first place? What is "absence of data," and how do we distinguish it from "a piece of data"? Isn't it all just coded information and rules for interpreting it, in which case, the "absence of data" and the "presence of data" are just a distinction over coded states?

    Your "solution," BTW, is pretty much equivalent to using boolean false as the linked list terminator. Yes, I know it's not exactly the same, but basically, it relies on the negation of end.next evaluating to true. That's not meaningfully different from returning null for a failed lookup; you're basically changing (a) the choice of sigil (return something other than null whenfoo.next is a failed lookup), (b) the semantics of negation (so that the sigil counts as false for boolean negation).

  76. Think in terms of information, not "objects" by Estanislao+Mart�nez · · Score: 1

    Consider the situation of apples. If you have an apple, then something is in your possession. If you don't have an apple, what do you have? Do you have some sort of object that depicts your lack of an apple? Obviously not. Yet in the world of computers, we have this special piece of data that shows our lack of data. It's a bit like getting a certificate that you have no apples. The certificate accomplishes nothing except to fill a space that does not need to be filled.

    By thinking about this in terms of "having objects," you're distorting the whole issue.

    Think about it instead in terms of encoding facts about the world. If we want to record the fact that you have an apple, and that I do not, there are several ways we could choose to encode this. Some of them would require you to explicitly have an informational token for each fact, so that you needed one piece of data to encode "Joe has an apple," and another one to encode "Mary doesn't have an apple." Another scheme might have you just encode who has an apple, and specify that if it is not explicitly recorded whether some specific individual has an apple, you should infer that they do not.

    One kind of representation is appropriate for some applications, and one for others. Vague generalities about apples and "having" do absolutely nothing to guide how one should encode information in a computer.

  77. Re:Null is NOT just a value by Anonymous Coward · · Score: 0

    but aren't most applications, where performance is a consideration, written in C or C++? from what i have read, even C is to high level for many game coders as far as certain loops are concerned, so they will tweak them in assembly. i imagine writing in a more abstract language, would make this process impossible. what would you recommend as an alternative for writing ultra-fast programs? (serious question, i am a bit of a noob)

  78. Re:Null is NOT just a value by Anonymous Coward · · Score: 0

    Almost nobody writes assembly for games anymore. Some game are even done in (*gasp!*) Java or C++.

    The bottleneck is not the CPU anymore. It's the GPU. So the language you write most of the code in doesn't matter nearly as much as it used to. The DirectX/OpenGL calls matter. And the Pixel Shader code matters.

    Besides, compilers are so good at optimizing code that the vast majority of programmers would be hard pressed to do better by hand.

  79. worthless by Anonymous Coward · · Score: 0

    As you can see by the definition in iluvcapra's response, the C standard is vague enough to make "volatile" nearly worthless.

    In the Linux kernel, the normal usage of volatile is only considered legitimate on the clock tick counter called "jiffies". (there is also a gcc-specific meaning for assembly language) The use of volatile for memory mapped IO or thread-related stuff is considered a bug.

    Volatile is the wrong concept anyway. It marks a data object, but you really want to mark an access or the boundry between two accesses. The proper concept is a barrier and/or special read/write operations.

    1. Re:worthless by iluvcapra · · Score: 1

      As you can see by the definition in iluvcapra's response, the C standard is vague enough to make "volatile" nearly worthless.

      Volatile's purpose is to tell the compiler that every time an object's name is used, the abstract machine must evaluate the name strictly and cannot replace any reference to that object with an optimization, which is why it tends to casually make statically-allocated objects capable of passing values between two co-running functions... I admit though that, aside from hacking memory-mapped IO or threading, I cannot imagine a purpose for it, unless I was a compiler developer and was trying to isolate an optimization bug. I'll bet, aside from the platforms I'm aware of, it has some purposes, but in those cases it won't be portable.

      --
      Don't blame me, I voted for Baltar.
    2. Re:worthless by xilun · · Score: 1

      In most implementations volatile provides you nearly nothing when trying to do mmio, because the processor will do ooo or worse speculative execution if you take no other precautions.

  80. The problem is much much more deeper by kentsin · · Score: 1

    The computer system is a virtual simulation or abstract of the real world.

    There are many differents between them, and there are no way to sync them.

    If we are careful in reason mind, to use the computing system in the way it is designed, and stop trusting it when it is not working in designed condition, then we are safe.

    However, we have developed a cultural that we use the computer system without thinking its limit, without reasonable doubt. Too much trust there.

    The same abstraction difficulty happens all over the development, there are too many short cuts, clever hacks that make the computer system not represent the real world correctly, but all were not documented, no body even the developer known about it.

    All computer systems have such a fatal error waiting. Even you build in a safety device in the computer language will not solve the problem.

  81. Not by itself by Estanislao+Mart�nez · · Score: 1

    Is it not a tad arrogant to claim that he single-handedly is responsible for a billion dollars in mistakes?

    Frankly, just on its own, without more context, it's not possible to tell. It all comes down to whether he's saying it to boast of how important he is, or whether he is simply admitting a mistake that was widely copied by others.

  82. Null pointers can be valid in C. by Anonymous Coward · · Score: 0

    C and C++ don't have any notion of a "null" pointer. By convention, a pointer of (void*)0/NULL is invalid. However, a NULL pointer can be valid.

    BEHOLD! A VALID NULL POINTER ! (Only works on linux. :P )


    int *null_ptr = mmap( (void*)0, sizeof(int), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
    if(null_ptr == (void*)-1) ... handle errors.
    printf("null_ptr = %p\n", null_ptr);
    *null_ptr = 42;
    printf("*null_ptr = %d\n", *null_ptr);

    (You have to tweak /proc/sys/vm/mmap_min_addr for this to work)

  83. Logical vs. physical by Estanislao+Mart�nez · · Score: 1

    My problem is that null references are typically used to signal the ends of lists or the place where the tree ends. I could see using a variant type for this. Instead of pointing to null, the next to the last list element would point to a value that had the type 'last list element' and no pointer inside it.

    I think one thing that's confusing people in this argument is the failure to distinguish between logical aspect of data and the physical representation thereof.

    Variant types, as implemented by a language like Haskell, are primarily a logical construct. A variant type is a type whose members are the union of tagged values of other specified types. This kind of definition says nothing about pointers or null references; it's all about which values are members of each type.

    Singly linked lists are a variant type, whose members are (a) the empty list, (b) pairs that contain a list element and the rest of the list. This type can be physically represented in many ways, some of which will use nulls to represent the empty list, some of which will use a different primitive sigil value, and some of which will use a pointer to another memory object that signifies the end of the list. These are all equivalent from the logical perspective; the choice between them comes from implementation details, or application requirements that restrict the physical representation (which is why C is good for low-level programming and Haskell is not, since C gives you more and easier control over how your data is physically laid out).

    And there would be four varieties of tree node, leaf, left filled, right filled and both filled.

    This is probably the wrong kind of definition at the logical level, because it has more subcases than it needs. In pseudo-Haskell, here's one that would be simpler:

    data BTree a = Empty | Node (BTree a) a (BTree a)

    In English, a BTree of element type a is either the Empty tree, or a Node that has three fields: a left BTree of a, an a, and a right BTree of a. (This definition treats a "leaf" as a node where both branches are the empty tree.)

  84. Its about Types by Destrius · · Score: 2, Insightful

    I think the main issue here is that when you're developing a type system, you generally want the types to classify objects into certain categories that tell you things about them. So if I define some kind of a reference type, what I am saying is that an object of that type is a kind of a pointer to something.

    So now, if I allow null references, then my reference type is really saying that "objects of this type are pointers to either something or nothing". That's all well and fine, but it makes the type less precise, in that it conveys less information about the object it is categorizing.

    As it turns out, this lack of information is quite important because one of the most common things you have to check when you're given a possibly-null reference is whether or not it is null. You need to insert "if (ptr == NULL)" all over the place. Thus reference types which allow null references ultimately give me less expressive power.

    Most of the time null references are created because either an error condition must be reported (e.g. malloc fails), or it is unclear at some point in time whether or not an object exists. Error conditions can be better signalled using exception handling. As for cases where you're not sure if the object exists or not, then one possibility is to use an option type like in Standard ML:

    datatype 'a option = SOME of 'a | NONE

    This is a polymorphic type that says that either the object exists or it doesn't, and you can find out what the situation is by using a "case" statement on the datatype constructors:

    case foo of
        SOME(x) ==> ... [do something with x] ...
    | NONE ==> ... [the object doesn't exist] ...

    Thus by combining a reference type without nulls with an option type, you can create "reference option" types, which have all the flexibility of "with-null" reference types.

    But the cool thing is, you only ever need to check the "null-ness" of the object only once; once you do the check, you're handed a reference object which is guaranteed to be non-null. Thus you can easily partition your code into parts that will do the non-null check and those that assume all references handed to it are valid.

    This is why a good type system can make programming so much cleaner and easier :)

  85. C is real good for machine gunning the foot by dsmall · · Score: 1

    I tested hundreds of Mac software applications 'Back In The Day'. A bit more than half of all of them banged onto location 0. About 100% of Microsoft Mac apps crashed. This happened to not (immediately) crash the Mac because the Mac just happened to have RAM mapped there, but, since multiple applications were resident in memory, taking turns shooting at 0.Long, "Difficult to debug problems, often not repeatable, soon arose".
    [I do love that phrase; it covers so much agony so concisely].

    The Mac had a memory heap structure with "handles", which aimed at "pointers", which aimed at "memory blocks". From time to time, just to amuse developers, the Mac would compress memory to get rid of stale stuff. The handles would be updated but, a zero would go into the pointer you were trusting ...

    I was busy teaching the Atari ST 68000 computer to be a Mac at the time. The Atari ST had ROM mapped to locations 0-7. It bus-errored every time someone used a Nil pointer. This looked unsolvable unless I wanted to patch two zillion Mac programs.

    I finally looked at the problem in a very, very simple manner, and discovered the IW (instruction word) that had caused the crash was on the stack, and the PC (program counter) was a bit past the crash point due to prefetch. A dim flickering flight appeared over my head. What if I "back up" the PC to the Evil Instruction, disassemble it to get its length [I hear you sigh at the thought of writing a disassembler, but I did], advance the PC to the next instruction (so we're just skipping over "the store into 0.Long" here), put all this on the stack, and treat it like a "normal" exception interrupt ... "Return from Exception."

    And it worked! The 68000 came back from a crash!

    That one thing made all the difference.

    To this day I have wondered, though ... if the Atari ST had ROM there ... what happened to all the data written to location 0?

    *grin*

    David Small

  86. Why not use a wrapper class? by AlgorithMan · · Score: 1

    Once I've written a class for arrays, where you could turn range-checking on and off by a compiler-directive (so turning it off kicked the range check out of the binary code, making it fast again). This gives me the Idea of making a wrapper class for pointers - something like

    #define nullpointer_safety
    template<class T> class Pointer {
       private:
          T* pointer;
       public:
          Pointer(T* p) { pointer=p; }
          Pointer(const Pointer<T>& p) { pointer=p.pointer; }
          Pointer() { pointer=NULL; }
          // Might include garbage collection
          bool operator=(const T* p) {return pointer=p;}
          bool operator=(const Pointer& p) { return pointer=p.pointer; }
          bool operator==(const T* p) {return pointer==p;}
          bool operator==(const Pointer& p) { return pointer==p.pointer; }
          bool operator!=(const T* p) {return pointer!=p;}
          bool operator!=(const Pointer& p) { return pointer!=p.pointer; }
          void new() { pointer = new T; }
          void new(T x) { pointer = new T; pointer* = x; }
          void delete() { delete pointer; }

          T& dereference() {
             #ifdef nullpointer_safety
                if(p==NULL) {throw "trying to dereference a null-pointer";}
             #endif
             return *pointer;
          }
    };

    // examples:
    // Pointer<int> w; w.new(3);
    // Pointer<int> x = new int; x.dereference() = 5;
    // Pointer<Pointer<int>> y = &x; std::cout << y.dereference().dereference(); // writes 5 to stdout
    // Pointer<int> z; if(z!=NULL) { z.dereference() =  7;}
    // z.dereference() = 3; // throws an exception
    Although I'm not sure if this works with function-pointers...

    --
    The MAFIAA is a bunch of mindless jerks who will be the first up against the wall when the revolution comes
    1. Re:Why not use a wrapper class? by AlgorithMan · · Score: 1

      I meant
      void new(const T& x) { pointer = new T; *pointer = x; }

      --
      The MAFIAA is a bunch of mindless jerks who will be the first up against the wall when the revolution comes
  87. so what? by Anonymous Coward · · Score: 0

    it's better to crash early than to pass the wrong object.

  88. see djb by Nicolas+MONNET · · Score: 1

    He proposes using the following format (I believe he uses it in qmtp) instead of ^M terminated lines: first write the number of characters in ASCII digits, followed by a space to indicate the end of the number, followed by that number of character, and a ^M.
    In any case, you have to take care of quite a few things when serializing data for writing to disk / transmission.

  89. Two strings in a bar by this+great+guy · · Score: 2, Funny

    These two strings walk into a bar and sit down.
    The bartender says, So whatll it be?
    The first string says, I think Ill have a beer quag fulk boorg jdk^CjfdLk jk3s d#f67howe%^U r89nvy~~owmc63^Dz x.xvcu
    Please excuse my friend, the second string says, He isnt null-terminated.

  90. TFA talks specifically about NULL in OO languages by Anonymous Coward · · Score: 0

    More specifically when designing one of the very first OO languages.

    TFA also mentions Spec#.

    It should be mandatory for *any* Java programmer to use the @NotNull annotation not only on every single method return value but also on every single method parameter.

    If someone think this is impossible then it should be pointed to two things: millions line project doing just this (and having guidelines and "checkstyles" verification enforcing it) and a good OOA/OOD book (OO Analysis / OO Design).

    Null, as stated by the almighty Hoare, was a brainfart.

  91. The OO system of Seed7 has no Null-reference by Thomas+Mertes · · Score: 1

    Hello

    The OO system of Seed7 works without NULL pointers. See:

    http://seed7.sourceforge.net/manual/objects.htm

    Seed7 variables always refer to a legal value. This has advantages in many areas. There are no problems with with uninitialized variables and no NULL pointer errors are possible. But it is als not possible to use NULL to describe a missing value. If this feature is needed it must be reached in a different way. In most cases the default value provided by every type can be used as value with the meaning: Not initialized. The default value is just a normal value. You will not get an exception when it is used. IMHO the advantates of not having NULL outweigh the small drawback to describe missing values in a different way.

    Greetings Thomas Mertes

    Seed7 Homepage: http://seed7.sourceforge.net/
    Seed7 - The extensible programming language: User defined statements
    and operators, abstract data types, templates without special
    syntax, OO with interfaces and multiple dispatch, statically typed,
    interpreted or compiled, portable, runs under linux/unix/windows.

  92. Re:20 second explanation from idiot End Of Days by Anonymous Coward · · Score: 0

    Fuck off, APK.

  93. Re:20 second explanation from idiot End Of Days by Anonymous Coward · · Score: 0

    Fuck off, APK.

  94. Re:20 second explanation from idiot End Of Days by Anonymous Coward · · Score: 0

    How're you enjoying being stalked by APK? This could last for months, you know.

  95. End of days using "End of Days", eh? by Anonymous Coward · · Score: 0

    http://slashdot.org/comments.pl?sid=1145195&cid=27058191 Take a peek there, lol (& look @ his reaction here now). Truth hit home, & nothing hurts like the truth, & TOO EASY to push the right buttons in your limited brain... lol! Yes, but it really DOES look like the "end of days", of your using that 1 of many admitted registered accounts you use, to be a self modding loser no less here on this forums, lol, so keep posting as "End of Days" won't you? LOL, caught red-handed in the act of admitting to lameness! So how does it feel taking the same treatment you give others, now that the shoe is on the other foot in someone hassling you as you do others here constantly and are caught in errors due to your skimming as you were also caught in within the url exchanges above? You obviously are a miserable person who likes to spread that to others and the humiliation you brought on yourself was your own doing period. Don't worry: I'll keep pointing out you admit to using multiple accounts here in a bogus manner, so keep posting as End of Days, if you wish (I'll let YOU, take your name from you, as payback - again, you only did this to you, not I). Oh and like usual? Mommy isn't here to respond to one of your fits, so giving orders here is useless boy. Grow up, you do not own this website nor are you a moderator here, get it, "dull skull"?? Apparently not.

  96. End of Days using END OF DAYS account, lol! by Anonymous Coward · · Score: 0

    http://slashdot.org/comments.pl?sid=1145195&cid=27058191 Take a peek there, lol (& look @ his reaction here now). Truth hit home, & nothing hurts like the truth, & TOO EASY to push the right buttons in your limited brain... lol! Yes, but it really DOES look like the "end of days", of your using that 1 of many admitted registered accounts you use, to be a self modding loser no less here on this forums, lol, so keep posting as "End of Days" won't you? LOL, caught red-handed in the act of admitting to lameness! So how does it feel taking the same treatment you give others, now that the shoe is on the other foot in someone hassling you as you do others here constantly and are caught in errors due to your skimming as you were also caught in within the url exchanges above? You obviously are a miserable person who likes to spread that to others and the humiliation you brought on yourself was your own doing period. Don't worry: I'll keep pointing out you admit to using multiple accounts here in a bogus manner, so keep posting as End of Days, if you wish (I'll let YOU, take your name from you, as payback - again, you only did this to you, not I). Hilarious and get over the fact you have no power or authority here as the site owner or even the admins here. So quit giving orders, this isn't your mama who responds to that form of manipulation here boy.

  97. End of Days using END OF DAYS account, lmao! by Anonymous Coward · · Score: 0

    http://slashdot.org/comments.pl?sid=1145195&cid=27058191 Take a peek there, lol (& look @ his reaction here now). Truth hit home, & nothing hurts like the truth, & TOO EASY to push the right buttons in your limited brain... lol! Yes, but it really DOES look like the "end of days", of your using that 1 of many admitted registered accounts you use, to be a self modding loser no less here on this forums, lol, that was caught red-handed doing so & admitting to it so keep posting as "End of Days" won't you? LOL, caught red-handed in the act of admitting to lameness you 'court jester' clown! So how does it feel taking the same treatment you give others, now that the shoe is on the other foot in someone hassling you as you do others here constantly and are caught in errors due to your skimming as you were also caught in within the url exchanges above? You obviously are a miserable person who likes to spread that to others and the humiliation you brought on yourself was your own doing period simply because you are stupid. Don't worry: I'll keep pointing out you admit to using multiple accounts here in a bogus manner, so keep posting as End of Days, if you wish (I'll let YOU, take your name from you, as payback - again, you only did this to you, not I). What is it like being not only a psycho stalker on the internet, but also one stupid enough to get caught in using multiple accounts to "mod himself up" & 'self-support his points'? Hilarious - a moment of TRULY HIGH COMEDY! Some people never learn... and, apparently, you can dish it out, but you cannot take it! like a typical online punk.

    1. Re:End of Days using END OF DAYS account, lmao! by Anonymous Coward · · Score: 0

      I wasn't talking to you, dipshit.

    2. Re:End of Days using END OF DAYS account, lmao! by Anonymous Coward · · Score: 0

      Profamity now? You're only letting on even more that you have been caught and all you have is your tantrums and foul language now. You brought it on yourself, live with it, or give up the "End of Days" account (probably your fav., & that's reward enough for me). Not that you can cover your blatant error here in being caught posting as ac as well as having multiple registered accounts to mod yourself up & others down yet more, all via your own admission no less here -> http://slashdot.org/comments.pl?sid=1147437&cid=27056793 (LMAO - proof of your blatant stupidity and 'wannabe geek angst'). Is your IQ like, 10 below plant life or what there, "End of Days"?? It surely IS the "End of Days" of you using this multiple registered account here now. Well, that would be assuming you have pride, and do nothings/never will bes are usually of that calibre & at the "end of their days" (lol), they probably sit there wondering why they lived such a poor life.

    3. Re:End of Days using END OF DAYS account, lmao! by Anonymous Coward · · Score: 0

      Awwwww, poor baby - no one's listening to you at all anymore on this website because you, while posting as "The End of Days", have only played yourself posting under diff. registered accounts to try to create the illusion of others supporting you, and to moderate yourself up on top that way obviously and your also using ac to create your other "self-made supporters", and then your admitting to it here http://slashdot.org/comments.pl?sid=1147437&cid=27056793 What a loser.

  98. Re:Null is NOT just a value by manifoldronin · · Score: 1

    The theory of type checking is that the sooner an error is caught, the less likely it is to cause damage. Thus if null does not exist, errors will occur as soon as the non-existent reference is used.

    The result from a map.get("key") call often isn't dereferenced. Often the whole reason to make a get() call is to check the existence of a value. Some other times we simply want to put whatever we get into another collection type without actually using it.

    In my mind, NULL to programming languages is like 0 to numbers. The conceptual breakthrough in the invention of 0 lies in that we realized we could use a symbol to denote the case of "nothing", and thus save ourselves a lot of trouble. For example, some early civilization used a space to represent "no value" in their _hand-written_ numbers. Imagine all the confusion that would have caused - "is that one space or two?"

    --
    Tyranny isn't the worst enemy of a democracy. Cynicism is.
  99. my proposal: by Anonymous Coward · · Score: 0

    what else would you terminate it with without using something the string may contain?

    terminate every string with "HAHAHA DISREGARD THAT I SUCK COCKS"

  100. ..only that it was NaN.. by jlehtira · · Score: 1

    in that program of mine, writing an array of floating-point numbers.

  101. End Of Days BUSTED posting under multiple names by Anonymous Coward · · Score: 0

    You were correct. A flood of ac posts came right afterwards. Nice job flushing this multiple registered account loser 'The End of Days' right out of the camoflage thicket he likes to create using ac replies as well as his using multiple registered accounts to 'support himself' and mod himself up with. I saw that here, where he slipped and did the reverse of what he did here (replying only as himself after you said he would reply ac (which he has now, a flurry of them, lol, you got to him with his own words apparently)). Here, he was harassing others as he is wont to do by doing a load of ac posts -> http://slashdot.org/comments.pl?sid=1144517&cid=27027131 and then he posted miles deep into that exchange which gave him away I felt. Nobody would be reading that deep into that posting by that point and it appears to me that 'The End of Days' slipped and forgot to post as ac as others noted there also. It looks like it really is 'The End of Days' of The End of Days, using this 1 of his admittedly many registered accounts here. He's as easy to read as a book and guessing 1 of 2 numbers (easier) given to guess on (which is 50/50, but you have higher odds on The End of Days, and the proof came right after in you being correct he would flood us with ac posts).

  102. You are a scumbag The End of Days by Anonymous Coward · · Score: 0

    Your kind are the lowest kind of scumbag available online in being imposters and impersonating others as well as your using multiple accounts here to try to make yourself look good. Why don't you just give up, leave, or something that is not here around us because you make this entire website look bad The End of Days. It looks like it may be the * End of Days * of you using The End of Days as 1 of your admitted many registered accounts you post with here and use to mod yourself up with, and that sir, makes you a scumbag loser. I am sure others agree because just judging by your other posts on this website this week that seems to be the case. He is going to paranoically say "apk etc. etc." and sorry to disappoint you I am not this apk you told to fuck off. That's part of what gives you away by tossing names around. I looked at the trouble you caused over at windows it pro and now you are starting the same thing here Jeremy Reimer by keeping your multiple accounts here that you used over there to try to make yourself look good and you and your fatboy friend Jay Little were laughed out of there. Keep it up, because it is funny to watch you squirm now that you've been caught admitting to posting here under multiple accounts to mod yourself up, and I predict you are heading for another fall again Jeremy Reimer or Jay Little.

    1. Re:You are a scumbag The End of Days by The+End+Of+Days · · Score: 1

      Wow, you have a lot of time on your hands.

  103. I'd say the other way around w\ your many accounts by Anonymous Coward · · Score: 0

    http://slashdot.org/comments.pl?sid=1147437&cid=27056793 - Especially with all those multiple registered accounts you must have to juggle as you use those here to mod yourself up with and to make it appear as if others support you. Looking at your history here in your username shows me quite otherwise, and that people despise you here, especially this apk guy. I don't blame him.

  104. Re:20 second explanation from idiot End Of Days by Anonymous Coward · · Score: 0

    Why dont you instead of ruining threads with good information in them?

  105. Re:20 second explanation from idiot End Of Days by Anonymous Coward · · Score: 0

    Why don't you instead of ruining threads with good information in them?

  106. NULL refs are good by Anonymous Coward · · Score: 0

    One person's problems is another person's fortune.

  107. Impersonating me @ 4chan.org now? by Anonymous Coward · · Score: 0

    I see you are now impersonating me at the forums @ 4chan.org, by registering as myself there & posting excerpts of my posts here @ slashdot (some in their original form and altered ones as well from other sites also) as well as your admitting to using multiple registered accounts here (to mod yourself up and to make it appear as if you have supporters (not)).

    Bad move: That is just going to make me go to 4chan.org's hosting provider and have them remove it, & if that fails, I will employ the local law enforcement in their area to do so and to prosecute you as well, & strangely I think it's going to go FEDERAL pal.

    (Oh, & by the way - I've had to do this before to a Mr. Jeremy Reimer and Mr. Jay Little of arstechnica, who had their websites @ CrystalTech.com & petitiononline.com removed in their entirety or in large portions & was completely successful in exposing those 2 for the same type of garbage you are pulling here on this site and over @ 4chan.org):

    http://dis.4chan.org/read/prog/1235936964/1-40

    I came across this impersonation of myself online (via cuts & pastes of my posts here & from other websites, some original, some altered) right after I posted about Windows VISTA, Server 2008, & Windows 7 removing port filtering and also making it impossible to use a 0 inside of a HOSTS file to block out bad IP addresses. -> http://tech.slashdot.org/comments.pl?sid=1143349&threshold=-1&commentsort=0&mode=thread&pid=27012231

    This impersonation of myself "oddly" seems to have happened only after when I also caught one of your own here @ slashdot, "The End of Days" -> http://slashdot.org/comments.pl?sid=1147437&cid=27056793 caught admitting to using multiple registered accounts to "mod himself up" here and to use those same registered accounts to mod down others (on top of his use of ac submissions as well to also make it appear he has further supporters).

    The "The End of Days": I would be a bit worried now were I you, because now it's going to go out of my hands @ this point, & you're the only person who might have any reason to do so. Now, I will just go to the hosting provider involved for that website to take care of it, & if I get resistance of any kind, I will prosecute yourself, and any others involved, to the fullest extent of the law.

    Heh, it looks like this is truly "the end of days" of you being online, period, much less you constantly bothering others here or elsewhere online via your bogus methods of impersonating others or posting under diff. account names here & at other forums in order to do so. You only bring this on yourself, & it only takes me minutes to take care of.

    APK

    P.S.=> It's one thing to shame yourself here being caught admitting to using multiple registered accounts to mod yourself up with (something us ac's can never be accused of) ,b>but, to go & impersonate me there has legal implications, and that is just plain dumb... I have no pity for you here, this is a lesson you will have to learn just as Jeremy Reimer &/or Jay Little of arstechnica had to before (my friends & family suspect it is they once more, but I'll reserve judgement on that until the law & hosting providers do their end of it)... apk

  108. The End of Days you are a disgrace by MEK_LoveBug · · Score: 1

    Why don't you instead The End of Days? You have been caught admitting to using multiple registered accounts here and I cannot see any reason for that myself, other than you using them to mod yourself up and to make it appear as if you have supporters here, which at this point you clearly do not.