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.3 required=5.0 tests=BAYES_00,FREEMAIL_FROM, HEADER_SPAM autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,b30bd69fa8f63cb2 X-Google-Attributes: gid103376,public X-Google-Thread: fc772,b30bd69fa8f63cb2 X-Google-Attributes: gidfc772,public X-Google-ArrivalTime: 2003-06-13 01:15:14 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!newsfeed-east.nntpserver.com!nntpserver.com!chi1.webusenet.com!news.webusenet.com!pd2nf1so.cg.shawcable.net!residential.shaw.ca!news-out.spamkiller.net!propagator2-maxim!news-in-maxim.spamkiller.net!usc.edu!rpi!not-for-mail From: James Rogers Newsgroups: comp.lang.ada,comp.lang.c++.moderated Subject: Re: C bug of the day Date: 13 Jun 2003 04:17:30 -0400 Organization: AT&T Worldnet Sender: cppmods@netlab.cs.rpi.edu Message-ID: References: <1054751321.434656@master.nyc.kbcfp.com> <3ee8901a@andromeda.datanet.hu> NNTP-Posting-Host: netlab.cs.rpi.edu X-Original-Date: Fri, 13 Jun 2003 01:16:33 GMT X-Submission-Address: c++-submit@netlab.cs.rpi.edu X-Auth: PGPMoose V1.1 PGP comp.lang.c++.moderated iQBVAwUAPumIl0HMCo9UcraBAQH9tAH/ZjTMOvF11QdsZGO4a220XJqxcJcm5zXg UlHZc8UoaMCdr8qCNU4r0DYAMQPShG+IO6rhTjPSpqn6oTad2EFWLQ== =4jqv Xref: archiver1.google.com comp.lang.ada:39089 comp.lang.c++.moderated:68269 Date: 2003-06-13T04:17:30-04:00 List-Id: "Balog Pal" wrote in news:3ee8901a@andromeda.datanet.hu: > "James Rogers" wrote in message > news:Xns9397C17B49692jimmaureenrogers@204.127.36.1... > >> Interesting. Do you think the fundamental safety problem in C code >> is ininitialized integers? > > Not "the" bat a very seriously fundamental problem I find in practice. > >> What about memory leaks > > Memleaks: I find not a problem in C++. (it is in C) [user shall not > handle memory in C++, containers and self-managing classes can solve > that > problem.] Do you ever deal with C++ code written using C style primitives such as arrays? I understand that such code still exists. > >> de-referencing >> null pointers, and array bounds violations? > > null pointers: not really. Dangling pointers is a problem. But it is not > a > coding-level problem but more generic, object lifetime problem on the > design > level. I agree that pointer lifetime issues are a design issue. One of the sometimes more difficult rules in Ada deals with pointer lifetime issues. (In Ada they are called access variables, but the lifetime issue applies here.) The language has very strict rules about access value lifetimes. The compilers enforce those rules. The result is a very low occurrance of dangling pointers. > > Array bounds: C, not C++. As normally in C++ we use containers, and > those do > bounts checks in debug build, that's enough to cath the typos/offby1 > goofing. Generally. Again, what about C++ code written using C style primitives such as strings and other forms of arrays? What C++ allows, and provides for "free" with the STL, is the ability to wrap the C style primitives such as arrays in a class, with all the bounds checking built into the class. This provides safety at the expense of some efficiency. Although the STL is part of the language definition, it is not part of the language syntax. A C++ compiler cannot optimize out bounds checks from STL or other container classes. > My guess is "we're cool guys not using lint". ;-o > btw lint will pick every case of uninited variable I guess, how you tell > it > to pass those you actually want uninited? > >> The reason is that many programmers neglect to use tools such as >> lint, which support my point. Programmers are frequently lazy. > > Well, if it was part of the package -- I still don't know whether I used > it > or not. (More probably yes.) with C++ it's quite a crude tool, isn't > it? Do modern C++ compilers produce the level of diagnostic output available from (or better than) lint? > > Can you tune it to pick up most real problems while not producing 10 > times > more noise? This has always been an issue with lint. Tuning the output to give no false reports while still not missing any real problems is not easy. > >> A language that requires extra work to achieve safety will >> frequently be used to create unsafe programs. This is not >> because it is impossible to create safe programs with the language. >> It is because doing so requires extra work. > > Sure, that's why the other poster claimed the uninitialised is a bad > default > behavior. I agree it is bad. I just did not think it was the most often encountered problem. Ada goes a bit further in this area than most C++ programs. Ada allows you to define your own numeric types (as primitives, not classes). You are allowed to define several characteristics about these types. type My_Index is range 1..10; The above line defines an integer type with a valid range of values from 1 through 10 inclusive. Now, let's combine that definition with an array type definition: type Nums is array (My_Index) of Float; This defines an array type indexed by the type My_Index. Each element of the array is a Float. The compiler can now optimize out bounds checking for accessing an array of Nums. The only index type allowed is type My_Index. Every possible value of that type maps to an array element. Trying to assign an out of range value to a variable of My_Index causes the program to raise the exception Constraint_Error at run time. Note that it would be illegal to initialize a variable of My_Index to 0. 0 is not a valid value for My_Index. The Ada compiler detects the use of uninitialized variables. > >> On the other hand, a language that requires extra work to remove >> built in safety features will frequently be used to create safe >> programs. This is not because it is impossible to create unsafe >> programs with the language. It is because doing so requires extra >> work. > > And that is not so symmetric unfortunately. Most safety you must reach > at > the design level. The level of language features may be too far away > from > that to know what is safe, or what is reasonable. [sometimes even > design > falls on face, like the syncronised stuff in the first java containers.] In Ada, I would simply use a container type as a data member in a protected type definition. This allows me to have all the synchronization behavior I need without suffering performance hits for the container itself. One common Ada container type is an unbounded string. It behaves something like a Java String type. If I want to share that string between several Ada tasks (similar to Java threads) I do the following: protected type String_Buf is procedure Write(Item : in String); function Read return String; private Buf : Unbounded_String; end String_Buf; The above code defines the interface, and private data member, for a String_Buf. An Ada protected type is protected from inappropriate mutual access by tasks. In this case any task calling the Write procedure has exclusive access to the instance of String_Buf, while any task calling the Read function has shared access to the instance of String_Buf. This allows simultaneous reads and exclusive writes. Note that this access control is far more sophisticated than what is provided by Java synchronization. The actual implementation of the String_Buf type follows: protected body String_Buf is procedure Write(Item : in String) is begin Buf := To_Unbounded_String(Item); end Write; function Read return String is begin return To_String(Buf); end Read; end String_Buf; All locking and unlocking is implicit. Each assignment to Buf causes the contents of Buf to be adjusted to exactly the number of characters required. Dynamic memory issues are handled automatically, just as in C++ with proper constructors and destructors. Jim Rogers [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]