5 ms·
One mistake in the first native C compiler was that all struct arms were in the same namespace, so struct a { struct *a next; }; struct b { stru
by williamDafoe 7y ago
One mistake in the first native C compiler was that all struct arms were in the same namespace, so
struct a {
struct *a next;
};
struct b {
struct *b next;
};
was illegal because the second declaration of "next" is a redeclaration.
- jstimpfle 7y agoIf you view member access as a (global) function on a value (possibly an lvalue), then it actually makes a whole lot of sense. I find code dealing with structures that have their members prefixed with a unique prefix much easier to read, usually. Given the pervasiveness of APIs that contain struct definitions nowadays, it's also understandable that the unique-constraint was removed.
- willtim 7y agoIndeed and Haskell still has this issue today, because member access is a top-level function.
- marcosdumay 7y agoStill, it creates all kinds of problems for code generation (templates) and code by convention (as with generic). I have not seen a case of it creating problems where there weren't already plenty of other problems with the code and metaprograming had to be abandoned anyway. But it does create problems.
- int_19h 7y agoIt would make more sense if fields actually were functions, or at least function-like in syntax. Then again, OCaml still has module-scoped scoped record field names today, even though it also uses the dot syntax.
- asveikau 7y agoThis is true. It also explains why a lot of old-time Unix struct member names (including a lot that made it into POSIX or are otherwise in use today) have redundant-seeming prefixes. eg. struct stat has st_mode and not simply mode. struct sockaddr_in has sin_addr and not simply addr.
- huhtenberg 7y agoOhhhh... damn. Obviously :)
- wahern 7y agoThat's still common today for subsequent interfaces as it makes it possible to write macros for preserving API compatibility. For example, to upgrade (struct stat).st_mtime to sub-second granularity you could do: #define st_mtime st_mtimensec.tv_sec POSIX preserves many prefixes for this reason. C99 brought anonymous unions (a Plan 9 invention), which makes many of these API tricks possible without using macros.
- wahern 7y agoCorrection: C11 brought anonymous unions, which perhaps explains why they're not used in standard headers. Standard headers on most unix systems do make use of C99 features these days.
- asveikau 7y agoThanks for looking that up, I didn't know the timeframe on that feature. I've known for a long time that Microsoft headers make use of anonymous unions, which makes it a rare case where they have implemented a recent ISO C feature ahead of time. I seem to recall GCC in the same timeframe would accept this with a warning that it's nonstandard. [I guess not anymore.]
- wahern 7y agoIn addition to C11's anonymous untagged members, struct foo { union { int i; double d; }; } Visual Studio also supports anonymous tagged members, union bar { int i; double d; }; struct foo { union bar; }; Is the latter more common in Microsoft land? I've always thought the latter were more useful and wished they were standardized. Anonymous tagged fields make it possible to reuse plain struct and union definitions, permitting a simple form of inheritance; whereas with untagged fields you have to rely on macros for sharing definitions. GCC (https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html) and clang (confirmed macOS clang-1001.0.46.4) support anonymous tagged members with -fms-extensions, but I can't bring myself to make use of it as I still try to keep many of my projects working with Sun Studio and otherwise try to avoid non-standard features.
- _kst_ 7y agoI wouldn't call it a mistake. That's how the language was defined at the time. If it was a mistake, it was a mistake in the language, not in the compiler. (Admittedly, given the lack of a standard at the time, the line between the two is less clear than it is now.)
- samatman 7y agoIn an era where line editors were a standard tool, and sed and awk were invented to do bulk changes on code, this is a defensible choice.
- jolmg 7y agoDid you mean struct a *next; or was putting the asterisk before the type name legal back then?