Google グループは Usenet の新規の投稿と購読のサポートを終了しました。過去のコンテンツは引き続き閲覧できます。
Dismiss

Portability check in lint

閲覧: 1 回
最初の未読メッセージにスキップ

Tom Cunningham

未読、
1987/07/15 11:19:151987/07/15
To:
I noticed that in the latest release of Sun 3 software which we have (I
believe it is 3.2), there is no -p option for lint to perform portability
checks. This option does exist, however, in the System V version of lint
presumably distributed with the Sun 3.2 software.

Did Berkeley lint (if there is such a thing) ever have this option, was
it excised for some reason, or what? I am just curious, as I consider
the constraints of eight character symbol names (six characters external)
as somewhat of an anachronism portability-wise, but I could well be wrong.

Would anyone care to comment on this? Apologies if this topic has already
been discussed at length; in that case if someone could email me a brief
synopsis I would appreciate it.
--

Tom Cunningham "Good, fast, cheap -- select two."
USPS: Motorola Inc. 6501 William Cannon Dr. W. Austin, TX 78735-8598
UUCP: {ihnp4,seismo,ctvax,gatech}!ut-sally!oakhill!tomc
sun!oakhill!tomc
Phone: 512-440-2953

Guy Harris

未読、
1987/07/15 18:53:241987/07/15
To:
> I noticed that in the latest release of Sun 3 software which we have (I
> believe it is 3.2), there is no -p option for lint to perform portability
> checks. This option does exist, however, in the System V version of lint
> presumably distributed with the Sun 3.2 software.

The "-p" option is, in fact, supplied with the System V version of
"lint", but not with the 4.2 version.

> Did Berkeley lint (if there is such a thing) ever have this option, was
> it excised for some reason, or what?

Yes, there is a version of "lint" that comes with 4BSD; in fact,
there was a version of "lint" that came with V7. Both those versons
have the option.

> I am just curious, as I consider the constraints of eight character
> symbol names (six characters external) as somewhat of an anachronism
> portability-wise, but I could well be wrong.

I suspect this may be why the "-p" was excised at Sun (I don't know
for sure, it happened before I joined). The trouble with "lint -p"
is that it's *too* strict for most uses. It checks for compatibility
with some old IBM 370 and GCOS dialects of C; this is why the the
6-character *one-case* external symbol name restriction is imposed.

Furthermore, instead of checking against the "lint" library for the
standard C library, it checks against some small library that
presumably represents the intersection of the libraries available
under the C implementations at Bell Labs. (The version that comes
with the S5 "lint" seems larger than the version that comes with the
V7 and 4BSD "lint"s. I don't know whether this reflects additions to
the OS or GCOS versions of the C library subsequent to the release of
V7, or not.)

The trouble is that there are some checks, performed only by
"lint -p", that are useful when porting to other UNIX
implementations, but specifying "-p" performs stricter checks than
are useful when testing for portability to UNIX C implementations (or
even to other modern C implementations). There really needs to be an
option intermediate in stringency between "lint" and "lint -p";
"lint -p" itself is of limited use.
Guy Harris
{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
g...@sun.com

Robert Gardner

未読、
1987/07/16 12:40:191987/07/16
To:
We recently received a large amount of code written for our
Unix VAX in C. It's device driver routines make extensive use
of an interesting construct -- a rather large number of #defines
are of the form:
#define a(n) a/**/n
so that, for instance, a(2) expands to a2. (Someone tried to tell
me that /**/ was a special c concatenation operator!:) This somehow
made it easier to write code for many devices -- you choose the
device you have, include its header, and compile.
I seem to remember, though I can't find it, that K&R says that comments
can occur anywhere white space is allowed, which suggests that this
construct should not work. In pursuing this (out of curiosity), I
found that the Ultrix VAX c compiler compiles the program
main()
{
int n2=2;
printf("%d\n",n/*comment*/2);
}
and prints out '2' when executed. This suggests that the pre-processor
simply removes comments, rather than replacing them with white space.
My Lightspeed C compiler at home will not compile the above program.
Any comments on portability?

Robert Gardner

Doug Gwyn

未読、
1987/07/16 15:07:221987/07/16
To:
In article <23...@sun.uucp> guy%goro...@Sun.COM (Guy Harris) writes:
>"lint -p" itself is of limited use.

I agree that the UNIX System V "lint -p" is not very useful to me either.
However, it would perhaps be useful in the near future for "lint" (no -p)
to check for inter-POSIX portability and for "lint -p" to check for inter-
X3.159 (ANSI C) portability, since those will be the two major vendor-
independent portable environments of interest.

Guy Harris

未読、
1987/07/16 15:30:091987/07/16
To:
> Any comments on portability?

Yup. The "/**/" hack is NOT portable. Plenty of other hacks
supported by the "Reiser preprocessor" supplied with most UNIX
versions are non-portable as well. The ANSI C draft proposes a
different mechanism for doing token concatenation.

M.P.Lindner

未読、
1987/07/17 10:07:251987/07/17
To:
In article <49...@prls.UUCP>, gar...@prls.UUCP writes:
> We recently received a large amount of code written for our
> Unix VAX in C. It's device driver routines make extensive use
> of an interesting construct -- a rather large number of #defines
> are of the form:
> #define a(n) a/**/n

The C++ compiler generates things of this form to concatenate names for the
same reason - you avoid naming conflicts by concatenating the name with some
type information or something. Apparently, this is making use of an obscure
BUG in the C preprocessor as implemented under UNIX(R) SYS V. Before you send
flames that this is NOT a bug, realize that, as the poster of the original
article pointed out, by not replacing the comment with white space, the
preprocessor is changing the semantics of the code! I know, it's SUPPOSED to
change the code, but this is abominable! K&R specify that comments act as white
space and may be used anywhere white space may be used. This implies that
a/**/b == a b
which is NOT the case!

I therefore claim the preprocessor is broken and if you want to concatenate
symbols, perhaps you should design a feature in the preprocessor to do so,
rather than exploit a bug! Oh, by the way, BSD systems use

#define blah(a,b) a\
b

to do the same thing (concatenate a and b). This seems more reasonable,
since K&R state that a '\' and an immediately following newline are ignored
(at least in strings).

BOTH of these methods has the disadvantage that white space in the arg list
will break the intention of the macro, so they don't preserve the "free format"
concepts of C. For example:
blah(abc, def)
will NOT work, while
blah(abc,def)
will. This took me 3 days to debug when I was learning C++.

Alastair Mayer

未読、
1987/07/28 16:03:461987/07/28
To:
In article <49...@prls.UUCP> gar...@prls.UUCP (Robert Gardner) writes:
>We recently received a large amount of code written for our
>Unix VAX in C. It's device driver routines make extensive use
>of an interesting construct -- a rather large number of #defines
>are of the form:
>#define a(n) a/**/n
>so that, for instance, a(2) expands to a2.
> [...] In pursuing this (out of curiosity), I

>found that the Ultrix VAX c compiler compiles the program
> main()
> {
> int n2=2;
> printf("%d\n",n/*comment*/2);
> }
>and prints out '2' when executed. This suggests that the pre-processor
>simply removes comments, rather than replacing them with white space.
>My Lightspeed C compiler at home will not compile the above program.
>Any comments on portability?
>
>Robert Gardner

You are right, the C pre-processor does (normally) strip out the comments.
However, the exact semantics depend on the particular version (BSD or
SYSV) of 'cpp'. There *are* uses for this -- you note one. The C++
compiler (which also uses 'cpp') uses a similar mechanism to allow definition
of generic classes. The file <generic.h> has code something like:

#ifdef BSD /* BSD way */
#define name2(a,b) a\
b
#else /* System V way */
#define name2(a,b) a/**/b
#endif

You might try the former method with your Lightspeed C (never having used
it, I dunno if it'll work either).

As to portability, if you *must* catenate tokens like this, then #define
a macro to do it such as the above.
--
Alastair JW Mayer BIX: al
UUCP: ...!utzoo!dciem!nrcaer!cognos!geovision!alastair

(Why do they call it a signature file if I can't actually *sign* anything?)

Neil Hunt

未読、
1987/07/31 13:23:001987/07/31
To:
alas...@geovision.UUCP (Alastair Mayer) writes:
> #ifdef BSD /* BSD way */
> #define name2(a,b) a\
> b
> #else /* System V way */
> #define name2(a,b) a/**/b
> #endif

I have seen a different construction, which looks more portable to me:

#define Same(token) token
#define Join(left, right) Join(left)right

Neil/.

Guy Harris

未読、
1987/07/31 13:45:121987/07/31
To:
> You are right, the C pre-processor does (normally) strip out the comments.
> However, the exact semantics depend on the particular version (BSD or
> SYSV) of 'cpp'. There *are* uses for this -- you note one. The C++
> compiler (which also uses 'cpp') uses a similar mechanism to allow definition
> of generic classes. The file <generic.h> has code something like:
>
> #ifdef BSD /* BSD way */
> #define name2(a,b) a\
> b
> #else /* System V way */
> #define name2(a,b) a/**/b
> #endif

I don't understand this. I have seen this several times, and I still
don't understand this. Why is the second way labeled "System V
way", and the first way labeled "BSD way"?

gorodish$ rlogin sunvax
Password:
Last login: Sat Jul 18 00:53:39 from gorodish
4.3 BSD UNIX #1: Mon Jul 7 11:46:47 PDT 1986

*** N.B.: Running straight 4.3bsd. ***
% ed foo.c
?foo.c
a
#define name2(a,b) a/**/b

name2(foo,bar)
.
w
42
q
% cc E foo.c
# 1 "foo.c"


foobar

The second way, mislabeled "System V way", works just fine on 4.3BSD;
the C preprocessor hasn't changed much at all between 4.1BSD and
4.3BSD, other than having the "-M" flag added. The "System V way" is
used in several places by 4BSD Makefiles.

If you're using a Reiser preprocessor, the "System V way" will almost
certainly work. If you're not using a Reiser preprocessor, *neither*
of the ways is guaranteed to work. (If you're using an ANSI C
preprocessor, there is, of course, a standard way of doing this that
*is* guaranteed to work, unless they change that part of the standard
before it becomes final.)

Note, by the way, that due to the Reiser preprocessor's Principle of
Least Surprise-violating way of handling white space in macro calls,
the following call of "name2" will not work with *either* of the two
definitions above:

name2(foo, bar)

It expands to "foo bar", because the second argument is " bar", not
"bar".

Doug Gwyn

未読、
1987/08/01 23:09:551987/08/01
To:
In article <1...@spar.SPAR.SLB.COM> hu...@spar.UUCP (Neil Hunt) writes:
>#define Same(token) token
>#define Join(left, right) Join(left)right

Presumably the last line should have read
#define Join(left,right) Same(left)right
but that still doesn't work in general, since the token resulting
from the macro expansion should not be spliced onto the token to
its right, at least not during macro scanning and replacement.

I think the outcome of the X3J11 work on this is that preprocessing
will be forced to tokenize, and splicing will require explicit use
of the new ## operator. Meanwhile, the above trick (with the bug
fixed) is probably the most universal approach. Be careful not to
include whitespace in the macro invocation argument list.

新着メール 0 件