Monday, April 26, 2021

Digest for comp.lang.c++@googlegroups.com - 3 updates in 1 topic

Eli the Bearded <*@eli.users.panix.com>: Apr 26 10:19PM

> there was C code we'd just about recognise in about 1973 or 4, but some
> of it would fool even gcc today. The biggest change was the great =<op>
> to <op>= switch. This silently changed the meaning of a lot of code.
 
Maybe five years ago I tried to compile some C code I found in buried
in a tar file on a dusty ftp server[*]. The READ_ME implied it was last
touched in June of 1980, the filename agreed with the year.
 
Things I found tricky about the code:
 
1. It predated printf being called that. I think it was just using
print(). And that used "-lS" in the Makefile.
 
2. Prototypes? Who needs em? ("#include <stdio.h>"? What, why?)
 
3. No need to declare ints, eg:
main(argc, argv)
char **argv;
{
 
4. Structs are implicitly unions:
struct plot {
char p_x;
char p_y;
} p_plot[LIM_PLOTS];
 
/* ... */
 
struct {
int p_xy; /* used to set/transfer entire plot */
};
 
5. Implicit in above: seems like there is the expectation that
sizeof(int) == 2.
 
 
Items 1 to 3 made things difficult. Items 4 and 5 meant actual code
audits were needed.
 
[*] I last saw it here, but that 404's today:
http://mirror.cc.vt.edu/pub2/Ancient_Unix/Applications/Shoppa_Tapes/usenix_80_delaware.tar.gz
 
Elijah
------
the .c files were easier to make sense of than the .o files included
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Apr 26 04:07PM -0700


> Things I found tricky about the code:
 
> 1. It predated printf being called that. I think it was just using
> print(). And that used "-lS" in the Makefile.
 
I believe printf is older than C. A form of it existed by that name in
B, and it's used (with an implementation presented) in the 1974 and 1975
editions of the C manual. But a particular program might have chosen to
use something else.
 
> 2. Prototypes? Who needs em? ("#include <stdio.h>"? What, why?)
 
Prototypes still aren't mandatory, though calling printf without a
visible declaration has been a constraint violation since 1999 (and
undefined behavior in C89/C90, but very likely to work).
 
> main(argc, argv)
> char **argv;
> {
 
Valid in C90. Add "int" to main and argc and it's still valid (but
obsolescent).
 
 
> struct {
> int p_xy; /* used to set/transfer entire plot */
> };
 
A struct member name implied a type and offset, and was not tied to
the struct type. That's why a lot of member names have unique prefixes,
like tm_sec and friends. I think C89/C90 changed that.
 
> 5. Implicit in above: seems like there is the expectation that
> sizeof(int) == 2.
 
There were implementations with sizeof(int)!=2 as early as the late
1980s, but there's never been any shortage of non-portable code.
 
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
Joe Pfeiffer <pfeiffer@cs.nmsu.edu>: Apr 26 05:08PM -0600


> Things I found tricky about the code:
 
> 1. It predated printf being called that. I think it was just using
> print(). And that used "-lS" in the Makefile.
 
It was called printf() at least as long ago as Kernighan's "Programming
in C - A Tutorial", which dates from 1974. So the print() you came
across was some other function.
 
 
> struct {
> int p_xy; /* used to set/transfer entire plot */
> };
 
*Lord* that one bit me hard early on. Having all struct members
use a single namespace is a decision I still don't understand (I don't
care how limited the machines running the compiler were).
 
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: