Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!rutgers!mit-eddie!uw-beaver!ubc-vision!alberta!bjorn From: bjorn@alberta.UUCP Newsgroups: comp.arch,comp.lang.c Subject: Re: String Processing Instruction Message-ID: <299@pembina.UUCP> Date: Tue, 21-Apr-87 19:15:30 EST Article-I.D.: pembina.299 Posted: Tue Apr 21 19:15:30 1987 Date-Received: Thu, 23-Apr-87 23:52:40 EST References: <15292@amdcad.UUCP> <693@jenny.cl.cam.ac.uk> <4605@utcsri.UUCP> Organization: U. of Alberta, Edmonton, AB Lines: 38 Xref: utgpu comp.arch:992 comp.lang.c:1779 In article <4605@utcsri.UUCP>, greg@utcsri.UUCP writes: >In article <693@jenny.cl.cam.ac.uk> am@cl.cam.ac.uk (Alan Mycroft) writes: >> #define has_nullbyte_(x) ((x - 0x01010101) & ~x & 0x80808080) >>Then if e is an expression without side effects (e.g. variable) >> has_nullbyte_(e) >>is nonzero iff the value of e has a null byte. > >If one of the bytes contains 0x80, then has_nullbyte() will >say 'yes'. This can be circumvented by a more thorough test >after this one to see if there really is a null there. You're mistaken the "has_nullbyte_(x)" defined above works as advertised for all 32 bit x. That is to say it returns a nonzero result if and only if x contains a null byte. >Someone posted a similar but usually better test on comp.arch ( I think ) >a little while ago: > >#define has_nullbyte(e) ((e+0x7efefeff)^e)&0x81010100) != 0x81010100 > >This one is only 'fooled' by an 0x80 in the most significant byte. >which makes the following test much simpler ( a sign test ). You are right this one does not always tell the truth. Besides it's a lot more effort. However for tricks like these to work reliably (especially on systems with memory protection) you had best get help from your local linker and 'malloc'. Otherwise one day a program is going to read off the edge of an accessible hunk of memory and flush your program straight down the drain. Making sure that no data item ends closer than n-1 bytes (if you're reading n bytes at time) from a boundary (between accessible and inaccessible memory) fixes this. Bjorn R. Bjornsson {mnetor,ihnp4}!alberta!bjorn