On Jan 1, 2012, at 16:48, Thomas David Rivers wrote:
>> On Dec 30, 2011, at 12:44, Thomas David Rivers wrote:
>>>
>>> This frequently lulls C developers on MVS into believing the
>>> runtime there checks for dereferencing NULL and does something
>>> "meaningful" with it; or that, for example, strlen(NULL) returns
>>> 0... but nope - it's just luck.
>>>
>> Actually, not entirely. It was mentioned on MVS-OE several
>> years ago that many UNIX systems keep a 0 at location 00, and
>> many C programmers have come to depend on this behavior, however
>> incorrectly. IBM got weary of problem reports, "But it works
>> on systems X, Y, and Z" that many library routines that used
>> to report "Invalid Pointer" were modified to substitute ""
>> for NULL and proceed accordingly.
>>
>> -- gil
>>
>
> Hmm - I can't think of a single UNIX implementation that
> does that by default; although I believe there are link-time
> options on Solaris/AIX and HP-UX and that will enable any number
> of facilities to cover-it-up; several of them requiring shared
> libraries.. but, the reader should check for himself.
>
<snip!>
Your example showed inline code. The change IBM made was for
function arguments. During the brief interval when I had
before-and-after IBM CRTL to test with, I tried (IIRC)
open( NULL, ... );
The older CRTL reported that the argument to open() was an
invalid pointer; the newer one (according to the discussion
on MVS-OE) performed a similar check for pointer validity,
but on detecting that it was NULL, substituted "" and tried
to open that pathname, and returned a less lucid error.
I'm not suggesting that any other implementor adopt the
latter behavior; IMO, the older one was preferable.
A recently re-created test program:
cat ../source/openNULL.c # ###############################################
#include <stdio.h>
#include <errno.h>
int TryIt( char *fname, char *remark ) {
FILE *fn;
errno = 0;
printf( "\narg is %s\n", remark );
fn = fopen( fname, "r" );
perror( fname );
return( fn==0 ); }
int main() {
TryIt( "", "Empty string" );
TryIt( NULL, "NULL Pointer" );
TryIt( ( char * ) -1, "( char * ) -1" );
return( 0 ); }
Run on Solaris:
./openNULL # ###############################################
arg is Empty string
No such file or directory
arg is NULL Pointer
Bad address
arg is ( char * ) -1
Segmentation Fault(coredump)
And on z/OS:
./openNULL # ###############################################
arg is Empty string
EDC5129I No such file or directory. (errno2=0xC00B04B3)
arg is NULL Pointer
EDC5129I No such file or directory. (errno2=0xC00B04B3)
arg is ( char * ) -1
CEE3204S The system detected a protection exception (System Completion
Code=0C4).
From entry point TryIt at compile unit offset +0000009E at entry offset
+0000009E at address 48ACC9F6.
[1] + Done(139) ./openNULL
50332029 Segmentation violation ./openNULL
Formerly, z/OS gave results similar to Solaris, which I prefer.
-- gil