From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,803df5f3f60558d5 X-Google-Attributes: gid103376,public From: ok@goanna.cs.rmit.edu.au (Richard A. O'Keefe) Subject: Re: Uninitialized "out" parameters Date: 1996/07/25 Message-ID: <4t7amf$701@goanna.cs.rmit.edu.au> X-Deja-AN: 170058704 references: <31EEACDA.64880EEB@sage.inel.gov> <4sq614$kai@mulga.cs.mu.OZ.AU> <4stagp$3vg@mulga.cs.mu.OZ.AU> <4t1s3n$chv@goanna.cs.rmit.edu.au> organization: Comp Sci, RMIT, Melbourne, Australia nntp-posting-user: ok newsgroups: comp.lang.ada Date: 1996-07-25T00:00:00+00:00 List-Id: dewar@cs.nyu.edu (Robert Dewar) writes: >Richard said > True, Ada is so designed that sound and complete compile-time detection > of using uninitialised variables is impossible. > But some day Ada will have a successor. And I can see no reason why that > successor should not do a better job than Ada in this respect. >I doubt it, you certainly do not suggest what that better job might be. I certainly *thought* I did. Reference to Mercury isn't a suggestion? Reference to Dijkstra's notation isn't a suggestion? Gosh, I'm on the wrong planet again. >From a requirements point of view, a better job is this: the *combination* of the run time checks and the static mode/type checks is such that any attempt to use an uninitialised variable will certainly be reported unless the programmer chose to suppress such checks. >The >rest of your note talks about checking that is not and cannot be completely >statically reliable. This is the same kind of hard-to-swallow straw man argument that Tom Lord is using in the GC list to argue "because it isn't perfect, you shouldn't say it's desirable." As long as the compile time checks can be suppressed, I don't *care* about the occasional false alarm. In the case of Mercury, the mode (instantiation state) system occasionally rules out at compile time programs that would have a reasonable interpretation, but this is no different from a type system, which also rules out at compile time programs that would have a reasonable interpretation. If memory serves me correctly, there was an Algol 60 compiler (I have the source, published by the CWI, but it's in Auckland) which allowed 'procedure' foo(N, A); 'value' N; 'integer' A; 'array' A; 'begin' 'if' N = 1 'then' A[1] := 0.0 'else' A[1,2] := 0.0; 'end'; with the type check done dynamically. In Ada, this is no longer allowed, and you don't say "the Ada type check cannot be completely statically reliable", you say "programs that don't make it through the Ada type system are *usually* wrong, so we think it's a good tradeoff that some programs are rejected even though no "type" error would have occurred at run time." >As for practical tools, any good Ada compiler should >indeed warn of many common cases, and tools analogous to lclint are >perfectly possible with Ada, and/or should be built into the Ada compiler. Here, if nowhere else, we are very much in agreement. So let me show you an example of the kind of thing that gcc warns about for C, that the Ada compiler available to our students does not warn about. Script started on Thu 25 Jul 1996 06:12:11 PM EST g% cat undef.adb with Ada.Text_IO, Ada.Integer_Text_IO; procedure Undef is X, Y: Integer; begin Ada.Integer_Text_IO.Get(Y); if Y = 0 then X := 1; end if; Ada.Integer_Text_IO.Put(X); Ada.Text_IO.New_Line; end Undef; g% rm undef undef.ali undef.o g% gnatmake undef gcc -c undef.adb gnatbind -x undef.ali gnatlink undef.ali g% ./undef 1 0 g% rm undef undef.ali undef.o g% gnatmake undef -cargs -O2 -Wall gcc -c -O2 -Wall undef.adb gnatbind -x undef.ali gnatlink undef.ali g% ./undef 1 1 g% script done on Thu 25 Jul 1996 06:14:14 PM EST Never mind arrays, it is possible to do a much better job than this for scalars. I have read gnatinfo.txt version 1.98, and the pattern /un(-|)init/ does not occur in it, so if there is some option I should be setting to get a warning for this, I think it is pardonable that I have not found it. >Dynamic bounds of arrays do not help in compile time legality checking, so >I don't see what relevance they have. This is a lot like saying "the run time range checks in Ada do not help in compile time legality checking, so I don't see what relevance they have". In both cases, whether it is state or type we are talking about, the compiler checks what it can, and there is something left over to be checked at run time. Dynamic bounds help the compiler because they give it less work to do. They completely solve the 2Gb array example (which I haven't seen yet either, but I'm guessing) because all the compiler has to prove is that the array elements are accessed *through* the array, not by any other means which might bypass checking. >Let's try to focus a specific example, the one I gave before, and you tell >me how your improved approach will work at compile time to detect as >illegalities all references to uninitialized elements. >I have an array of 2 gigabytes in an allocate-on-demand environment. I use >this as a sparse hash table, but it is critical that only pages that are >actually used get referenced, so it is out of the question to initialize >the table. >How do I make sure that references to this array correspond to previously >set elements? Even doing this at runtime is awkward, but I see no way of >designing a type system or any other semantic framework to solve this at >compile time as a legality issue. Gosh, how this reminds me of the "Ada doesn't have bitwise operations, so we ought to do everything in C" arguments. I don't have a solution if you insist that the thing be modelled by a simple array. That's not a failure on my part, because I'm arguing that simple C-style arrays are a problem. Since we are talking about a very large structure, the structure is not a simple "uniform cost" structure anyway. What's really going on underneath is in some sense an array of pointers (the page table), and it's not going to cost us a lot to use a multilevel structure ourselves. Each page of that multilevel structure can be fully initialised when it is created. I have often done this. >It is not good enough to just say "we should do better", you have to say >*exactly* how you can do better, or your position is unconvincing. After >all, this is an old problem that has not been solved for 38 years now >(I am counting from Algol-58, it is a bit longer if you count from the >first Fortran), so if you have a solution, it would be nice to present it! There are a lot of old solutions, too. If you insist "but you MUST be able to handle arrays exactly the way they are now or I'll say Nyah-nyah", then you'll be saying nyah'nyah until the last proton decays. -- Fifty years of programming language research, and we end up with C++ ??? Richard A. O'Keefe; http://www.cs.rmit.edu.au/~ok; RMIT Comp.Sci.