gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/20/87)
In article <3865@uw-june.UUCP> pardo@uw-june.UUCP (David Keppel) writes: >>In article <3855@uw-june.UUCP> pardo@uw-june.UUCP (David Keppel) writes: >>>... how about adding a "pragma" which looks like a procedure call. [I had previously responded:] >>... I don't understand just what it is that you are proposing. >By adding even a small pragma mechanism to the language ... Ah, now I see why I didn't understand. The proposed ANSI C has had pragmas, in the form #pragma ...stuff... , for quite some time now. You're suggesting a different syntax, so that the preprocessor can be used to disable pragmas.
mccarrol@topaz.rutgers.edu (<MC>) (12/24/87)
With all of the discussion lately about #pragmas vs noalias, I thought I'd ask a simple ( and probably stupid) question: What is a pragma, and what is the function of #pragma in C? <MC> -- Mark C. Carroll | a man in black on a snow white horse. Rutgers University CS Student | a pointless life has run its course. ARPA: Carroll@aim.rutgers.edu | the red rimmed eyes, the tears that run UUCP: mccarroll@topaz.rutgers.edu | as he fades into the setting sun
cr@hpcilzb.HP.COM (Cindy Roberts) (12/30/87)
> What is a pragma, and what is the function of #pragma in C?
I would also like a clue!
-Cindy
kgregory@bbn.COM (Keith D. Gregory) (01/01/88)
In article <1620005@hpcilzb.HP.COM> cr@hpcilzb.HP.COM (Cindy Roberts) writes: > >> What is a pragma, and what is the function of #pragma in C? > >I would also like a clue! A #pragma statement is "a compiler non-specific way of indicating compiler specific actions". . . a portable way of saying that you have non-portable code. On the surface, this seems to be a good idea - if your compiler sees a #pragma that it doesn't recognize, then it abends. If it does recognize a pragma, then it may (or may not) shift into a special processing mode. Of course, as far as I can tell, there are absolutely no controls on the use of #pragma directives. Two compilers could use the same directive to do different things (picture #pragma assembly, to indicate the use of inline A/L), and fail radically when code for one is compiled under the other. So, to all the people "who really know" . . . is there any good reason for #pragma's existance (I don't consider the above mentioned reason to be "good") -kdg
pardo@uw-june.UUCP (David Keppel) (01/01/88)
["A pragma is a non-specific way of indicating compiler-spcific actions" . . . a portable way of saying that you have non-portable code] Pragmas are not _necessarily_ portability issues. For example the PACKED keyword in Pascal is a "pragma" saying that data is to be stored in a space- efficient (rather than a time-efficient) way. A compiler can safely ignore the PACKED "pragma" as long as the programmer didn't write any code that depends on the code being packed. Note, BTW, that PACKED data can be *faster* to copy than unpacked data, so what I said above is a lie - it doesn't really mean "instead of time- efficient", but that's the general idea. ;-D on (I just PACKED my bags and my toothbrush access time went up) Pardo
minow@thundr.dec.com (Martin Minow THUNDR::MINOW ML3-5/U26 223-9922) (01/03/88)
bbn!kgregory asks for examples of #pragma usage. Here are a few: -- Decus C has compiler-specific keywords to determine storage allocation (program sections) -- this let you write data into specific areas that were resolved to absolute base addresses by the linker. This is essential if you are writing a program that will subsequently be run from ROM; you must force code and tables into read-only memory and non-static data into ram. This also let us develop a facility that called specific functions at the start and/or end of execution. The function registry mechanism used program sections to manage a table of routines to call: all of the mechanism was done by the compiler. The Draft Standard has an "atexit()" registry that is managed by explicit calls by the running program. Decus C has both "atexit" and "atentrance" which are triggered by the inclusion of the module, and require no programmer intervention. -- On some architectures, such as the Vax, certain instructions may not be used to access device registers. A statement such as #pragma device_register foo, bar; might be useful to prevent certain optimizations. Note that the architectural restriction goes beyond what "volatile" can accomplish. -- On architectures such as the 80x86 family, one can achieve useful optimization by adding "near" and "far" pragmas. -- One might use #pragma's to enable/disable debugging or self-testing code. While all of the above can be achieved by using implementation-specific keywords (beginning with _), #pragma is a useful addition to the language. According to the Draft Standard, unknown pragmas are to be ignored (section 3.8.6 of the Aug. '87 draft). Because it doesn't distinguish mistakes from typographical errors, this is a mistake, and one that the Committee seems inordinately fond of: they rejected my request to flag unknown pragmas as errors. The Gnu compiler "recognizes" all pragmas, causing them to run Towers of Hanoi to a depth of 64. This is proper usage per the Draft Standard. Martin Minow minow%thundr.dec@decwrl.dec.com decvax!decwrl!dec-rhea!dec-thundr!minow ======================================================================== Received: by decwrl.dec.com (5.54.4/4.7.34) id AA06740; Fri, 1 Jan 88 19:31:42 PST
dhesi@bsu-cs.UUCP (Rahul Dhesi) (01/03/88)
In article <8801021358.AA15890@decwrl.dec.com> minow@thundr.dec.com (Martin Minow THUNDR::MINOW ML3-5/U26 223-9922) writes: >According to the Draft Standard, unknown pragmas are to be ignored >(section 3.8.6 of the Aug. '87 draft). Because it doesn't distinguish >mistakes from typographical errors, this is a mistake, and one that the >Committee seems inordinately fond of: they rejected my request to >flag unknown pragmas as errors. Agreed. What we really need is a pragma that tells the compiler to ignore unrecognizes pragmas, and the default should be to flag unrecognized pragmas as errors. Unfortunately, it has been traditional (e.g. Pascal and Ada) for compilers to ignore unrecognized pragmas so ANSI is simply following well-trodden footsteps. This may not get fixed until a missile is actually lost in space due to a misspelled pragma. -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi
jgm@K.GP.CS.CMU.EDU (John Myers) (01/03/88)
In article <8801021358.AA15890@decwrl.dec.com> minow@thundr.dec.com (Martin Minow THUNDR::MINOW ML3-5/U26 223-9922) writes: >According to the Draft Standard, unknown pragmas are to be ignored >(section 3.8.6 of the Aug. '87 draft). Because it doesn't distinguish >mistakes from typographical errors, this is a mistake, and one that the >Committee seems inordinately fond of: they rejected my request to >flag unknown pragmas as errors. > >The Gnu compiler "recognizes" all pragmas, causing them to run Towers >of Hanoi to a depth of 64. This is proper usage per the Draft Standard. > Unfortunately, this feature of the Gnu C preprocessor went away in the latest version, 1.16. It now passes #pragma statements through untouched. Actually, a conformant compiler could "recognize" all pragmas not otherwise defined by the compiler as a command to issue an error. _.John G. Myers
rjchen@phoenix.Princeton.EDU (Raymond Juimong Chen) (01/03/88)
In a famous article, minow@thundr.dec.com (Martin Minow) said: >According to the Draft Standard, unknown pragmas are to be ignored >(section 3.8.6 of the Aug. '87 draft). Because it doesn't distinguish >mistakes from typographical errors, this is a mistake, and one that the >Committee seems inordinately fond of: they rejected my request to >flag unknown pragmas as errors. Why not flag unknown #pragmas as warnings? This would allow files to be compiled, while letting the user know that something may be amiss. If the user sees things like warning: unknown pragma directive: memory_model warning: unknown pragma directive: asm warning: unknown pragma directive: mispelled s/he can take appropriate action for each one. (The first can probably be ignored safely; the second will cause hair to be pulled out; the third is the kind of thing we need to catch lest our next spacecraft land in a rock garden instead of a flat surface.) Also, has dpANS (or however you capitalize it) made any attempts at standardizing #pragmas? To the extent of "If your compiler accepts #pragma sneeze, then the sneeze option must mean the following: ...", I mean. Is this a good idea? Is it practical? -- Raymond Chen UUCP: ...allegra!princeton!{pucc|phoenix}!rjchen BITNET: 6101695@pucc, rjchen@pucc ARPA: rjchen@pucc.PRINCETON.EDU "Say something, please! ('Yes' would be best.)" - The Doctor
ok@quintus.UUCP (Richard A. O'Keefe) (01/03/88)
In article <8801021358.AA15890@decwrl.dec.com>, minow@thundr.dec.com (Martin Minow THUNDR::MINOW ML3-5/U26 223-9922) gives some examples of #pragmas. (1) > (program sections) -- this let you write data into specific areas > that were resolved to absolute base addresses by the linker. (2) declaring variables to be device registers > #pragma device_register foo, bar; (3) > On ... the 80x86 family ... "near" and "far" pragmas. (4) > One might use #pragma's to enable/disable debugging > or self-testing code. The preprocessor (remember the pre-processor? all and only # lines are to be handled by the preprocessor, which has usually been implemented as a **SEPARATE** program) is the wrong place to handle each of these things. (1) To the extent that I understand it, this is a task for the loader. The System V "COFF" loader will let you do all of this and more. So does the VMS loader. (2) The appropriate way to handle this is with pragma(device_register) struct devreg foo; or whatever. The preprocessor is for handling file inclusion, conditional inclusion, and macro definition and expansion. Not for giving half of a declaration! (3) Many 80x86 C compilers already have 'near' and 'far' as keywords, and I really don't think they are going to go away. Let's face it, "char *near" is a 16-bit (8086) or 32-bit (80386) data type, and "char *far" is a 32-bit (8086) or 48-bit (80386) data type, and something that fundamental belongs in the language, not in the preprocessor. So the appropriate thing to do is NOT to say #pragma near fred #pragma far jim char *fred, *jim; but char *pragma(near) jim; char *pragma(far) fred; (4) This IS an appropriate use of the preprocessor, but we already have #if. The way to do it is e.g. #if DEBUG void display_thing(const struct foo *p) { ... } #else #define display_thing(x) (void)(x) #endif It used to be the case back in Version 7 that there were two independent programs: the C preprocessor the C compiler When I say that they were independent, I mean that (a) the C preprocessor was available as a separate program which could be called directly and could be used as a front-end to ANYTHING with C-like lexical structure. E.g. Yacc, Ratfor, ... (b) the C compiler could be invoked without using the C preprocessor. (If the first character wasn't a #, the preprocessor was not used.) Every facility of the C language (including all the libraries) could be accessed without using the preprocessor. In the interests of portability, a lot of things have been shunted off into "standard" header files. With faster machines than PDP-11/34s, and with portability-via-standard-macros as a desideratum, property (b) is not very important any more. But property (a) is still useful. I have often used the C preprocessor as a front-end to other tools, and very useful it is. It seems to me that it would be a serious mistake to FORCE the preprocessor to be strongly coupled to the compiler. Now, is #pragma something which forces the preprocessor to be strongly coupled to the compiler, or not? Well, if #pragma can be used to declare properties of identifiers, either the preprocessor has to be built into the compiler or else it has to write something into its output stream which recodes the information and the compiler has to reparse it. In this latter case, there is a strong coupling between the preprocessor and its particular compiler, because they have to agree on how the pragma information is recoded. The trouble with declaring properties of identifiers in the preprocessor is the interaction of those declarations with C's scope rules. Suppose I say int fred; /* 1 */ void jim() #pragma device_register fred { static int fred; /* 2 */ ... Which fred was affected? I can think of at least four different interpretations, and each of them is "natural" and "obvious" given a different method of coupling the preprocessor and compiler. Now since the compiler is going to have to do something with this information anyway, the obvious thing to do is to be efficient and have only ONE program know about it, namely the compiler, and write pragma(device_register) int fred; /* 1 */ void jim() { static int fred; or int fred; void jim() { static pragma(device_register) int fred; /* 2*/ and make it absolutely clear which one we mean? I mean, let's face it, playmates, handling pragmas in the pre-processor makes about as much sense as handling "long" or "short" there.
flaps@dgp.toronto.edu (Alan J Rosenthal) (01/04/88)
ok@quintus.UUCP (Richard A. O'Keefe) writes: >Now, is #pragma something which forces the preprocessor to be strongly >coupled to the compiler, or not? Well, if #pragma can be used to >declare properties of identifiers, either the preprocessor has to be >built into the compiler or else it has to write something into its >output stream which recodes the information and the compiler has to >reparse it. In this latter case, there is a strong coupling between >the preprocessor and its particular compiler, because they have to >agree on how the pragma information is recoded. How about having the preprocessor just pass them through? The compiler and the preprocessor already agree on how some lines beginning with # are passed through, namely the "# line file" lines. Just typing "/lib/cpp" gives me one. /lib/cpp will also pass them through. >The trouble with declaring properties of identifiers in the preprocessor >is the interaction of those declarations with C's scope rules. Suppose >I say > > int fred; /* 1 */ > void jim() > #pragma device_register fred > { > static int fred; /* 2 */ > ... > >Which fred was affected? I can think of at least four different >interpretations, and each of them is "natural" and "obvious" given >a different method of coupling the preprocessor and compiler. After ANSI standard C hits the streets, when you type "man cc", it will probably have a section describing pragmas, or at least it should. It will say something like "'#pragma device_register id' means that the next occurrence of 'id' is a device register". Or wherever it was you learned of the pragma's meaning in the first place. No problem. Two further comments on this: 1. that's a terrible construct anyway. 2. I can't think of your three other "natural" interpretations. -- "Bill Joy uses EMACS." - D. Hugh Redelmeier
ok@quintus.UUCP (Richard A. O'Keefe) (01/04/88)
In article <1988Jan3.162343.1697@jarvis.csri.toronto.edu>, flaps@dgp.toronto.edu (Alan J Rosenthal) replied my message about #pragma: > How about having the preprocessor just pass them through? The compiler > and the preprocessor already agree on how some lines beginning with # > are passed through, namely the "# line file" lines. Just typing > "/lib/cpp" gives me one. /lib/cpp will also pass them through. Passing #pragmas through to the compiler means that (1) /lib/cpp has to parse stuff which is significant to the C compiler, and ONLY to the C compiler. (2) /bin/cc has to parse something like the pragma(..) construct ANYWAY, the user just doesn't get told what it looks like (and so doesn't know how to *avoid* it). #line is a different case. The whole POINT of the preprocessor is to drop lines, expand macros, and generally do all sorts of things that can make it hard for the compiler to work out where anything came from. In fact, as your example shows, the main function of # <lino> <file> is not to be passed through by the preprocessor, but to be generated by the preprocessor. I have never written a # <lino> <file> in my life, but the preprocessor has made millions for me, BECAUSE THAT IS PART OF ITS JOB. (And it can be told not to. Try /lib/cpp -P) #line is **related to cpp's FUNCTION**. #pragma is not related to the function of the *preprocessor*. If you are going to pass #pragmas through to the compiler in some fashion, why not reserve one (count them, ONE) keyword for the thing that gets passed through, and standardise that? Something of the sort apparently has to be around anyway, and having just one keyword makes it easy to avoid. Perhaps I can make it a little bit clearer why, if pragmas are going to be in the language, having pragma(system-dependent-parenthesis-balanced-stuff) as something that can appear where 'noalias' would have been allowed, is a better way to go than having #pragma in the pre-processor. One of the things one wants to do with a program is to analyse it. For example, one would like to produce cross-referencers, static call graph analysers, "software metrics" tools, &c &c. We would like to write such tools ONCE for "ANSI C". The easiest way to hack this is cc -E source.c | analyser which means that your analyser doesn't have to be a preprocessor as well as a parser! The # <lino> <file> lines generated by the preprocessor tell you everything you need to know about where things came from (if you are doing a cross referencer or dependency analysis). If the "pragma" construct is defined as pragma(..) in the compiler language, then each tool has to be prepared to skip a parenthesis balanced sequence of tokens after pragma() but can otherwise ignore the construct. But if #pragma is a pass-through (as some quite undocumented form) then I can't defend my tool against it, because I don't know what the passed-through form is going to look like. Now the ANSI committee has rightly chosen not to specify the behaviour of the preprocessor as a separate program, or even that it IS a separate program, or even that "cc -E" should work. But they surely should not go out of their way to make life hard for people who want to write program analysis tools! > After ANSI standard C hits the streets, when you type "man cc", it will > probably have a section describing pragmas, or at least it should. It I have access to a compiler NOW on a S5.3 machine that has #pragma. The manual does NOT tell me what #pragma does. > will say something like "'#pragma device_register id' means that the > next occurrence of 'id' is a device register". Or wherever it was you > learned of the pragma's meaning in the first place. No problem. Yes, that will answer the "scope" problem. But my actual viewpoint is that I would like to be able to write tools that will work in the presence of pragmas(), without even having heard of the machine or its operating system, let alone having seen the compiler manual. I can do this for ADA. Why not for C? > Two further comments on this: > 1. that's a terrible construct anyway. > 2. I can't think of your three other "natural" interpretations. Two rejoinders: (1) #pragma device_register fred was *your* example. I merely pointed out the problem. (2) Thank you. I was hoping for that. I bet there are at least three implementors out there who also can't think what the three "other" interpretations are, and yours is one of the ones they can't think of. Which is why #pragma <property> <identifier> ; IS a terrible construct.
sms@sugar.UUCP (Stanley M. Sutton) (01/05/88)
I've yet to run into a vendor that hasn't "improved" a language with extensions for his particular hardware. If used properly, a pragma may be a useful way to extend a language that warns the code reader that something non-standard is being used. Code is almost always developed with two purposes in mind. The first is to solve a problem; the second, to allow someone else to understand both the problem to be solved, and the actual solution. Portability is a design criteria for some projects, efficency for others, and "getting it working" for others. Pragmas can be used for all three goals, if they are used and implemented correctly. For example, the use of inline assembly. A module can be developed in portable C until the application is functional. Time studies may then be performed on the code. If a memory transfer operation is taking a significant portion of the time of the application, the actual memory transfer may be done in assembly to take advantage of hardware specific features (such as the blitter and/or DMA controller on an Amiga) using #ifdef ... #else ... #endif to improve performance. Almost any feature available to a programmer can be used or abused. The feature is not inheriently good or bad. It's the purpose the programmer uses it to accomplish that is good or bad.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/06/88)
In article <17196@topaz.rutgers.edu> mccarrol@topaz.rutgers.edu (<MC>) writes: > What is a pragma, and what is the function of #pragma in C? A "pragma" is some advice to the compiler outside the scope of the language proper. Ada has these. Typically, pragmas are interpreted in an implementation-specific way. Typical usages include specifying various optimization preferences, producing listings, aiding debugging, etc. The proposed ANSI C provides a #pragma preprocessing directive but leaves the definition of its effects up to the implementation. My version of the Reiser C preprocessor accepts #pragma but ignores it. The main reason #pragma is not suitable for "noalias" is, as I showed in an earlier posting, the "noalias" property has potentially visible and important effect on the computation, depending on the code. Such code is "illegal", under the "noalias" approach, but it would have to be permitted if #pragma were used. A #pragma is not supposed to change the interpretation of the virtual-machine semantics of the code. At least, that's my interpretation of what's going on here.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/06/88)
In article <1766@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: >This may not get fixed until a missile is >actually lost in space due to a misspelled pragma. Since a #pragma is not supposed to change the abstract "virtual machine" operation, it's hard to see how this could happen. At the rate the USA is going, it's going to be a long time before a missile is actually fired into space!
dsill@NSWC-OAS.arpa (Dave Sill) (01/07/88)
Doug Gwyn writes: >In article <1766@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: >>This may not get fixed until a missile is >>actually lost in space due to a misspelled pragma. > >Since a #pragma is not supposed to change the abstract "virtual >machine" operation, it's hard to see how this could happen. Where does it say this? For the benefit of those without a copy of the dpANS, this is what it (Oct '86) says about pragmas: --------------- 3.8.6 Pragma Directive Semantics A #pragma preprocessing directive causes the implementation to behave in an implementation-defined manner. Any pragma that is not recognized by the implementation is ignored. --------------- The rationale says: --------------- 3.8.6 Pragma Directive The #pragma directive has been added as the universal method for extending the space of directives. --------------- Don't flame me for quoting the above, I couldn't find a copyright notice. >At the rate the USA is going, it's going to be a long time before >a missile is actually fired into space! Unless I'm mistaken, intercontinental ballistic missiles are fired through space. I certainly hope it's going to be a long time before such a missile is fired. ========== The opinions expressed above are mine. Which is worse: ignorance or apathy? Who knows? Who cares?
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/07/88)
In article <11137@brl-adm.ARPA> dsill@NSWC-OAS.arpa (Dave Sill) writes: >Doug Gwyn writes: >>In article <1766@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: >>Since a #pragma is not supposed to change the abstract "virtual >>machine" operation, it's hard to see how this could happen. > >Where does it say this? This is not explicitly stated; rather, it is deduced as follows: The requirements for a conforming implementation are defined by the standard as a whole, not just some portion of the standard taken out of context. A conforming implementation must simultaneously meet all specified constraints. Although the behavior of #pragma is not spelled out, other than requiring each implementation to describe its interpretation of pragmas, other portions of the standard impose constraints on the C language. If an implementation were to attempt to make its interpretation of some #pragma result in behavior counter to that specified in the rest of the standard, #pragma Pascal { The rest of this file is Pascal syntax! } for example, then the total total set of rules is self-contradictory; that is, such an implementation logically cannot be standard conforming. I chose the most reasonable example I could think of for a radically-contradictory pragma; if I had introduced a more subtle relevant one such as #pragma noalias variable_name then the point would have been harder to see, but it's logically the same issue. In fact, I used to think that the presence of #pragma "spoiled" the code, so that no portable application could ever contain a #pragma directive. But some other X3J11 committee members finally convinced me that pragmas could not violate the abstract machine semantics specified by the rest of the standard. I should note that at least one committee member has indicated that he still thinks the way I used to. If in fact I now have the intended, or at least the consensual, understanding of this, then it would probably be wise to have a discussion like the above in the Rationale document.
mwm@eris.BERKELEY.EDU (Mike (My watch has windows) Meyer) (01/07/88)
In article <5724@ccv.bbn.COM> kgregory@ccv.bbn.com (Keith D. Gregory) writes:
<So, to all the people "who really know" . . . is there any good reason for
<#pragma's existance (I don't consider the above mentioned reason to be "good")
I don't know about "a good reason for #pragma's existence," but I *do*
know of a case where they were put to good use.
AmigaDOS supports shared libraries. The interface is a jump table into
the library, with a pointer to the table being stored in a variable of
a known name. In assembly, the calling sequence looks like:
move.l <args>,<registers> ; arguments
movea.l SomeLibrary,a0 ; address table
jsr offset(a0) ; and go there
To use these things from C (vital - the OS interface looks like shared
libraries), it's normally done the same way as Unix: a stub routine in
assembler that takes the C arguments, puts them in the right
registers, and then jmps/jsrs to the real routine.
The latest version of the Lattice C compiler has a pragma for dealing
with shared libraries. It basically looks like:
#pragma routinename libraryname offset registers
This makes it generate an inline-call as the above, rather than a call
to a C stub that does the above. This means you get faster code, and
possibly slightly smaller code (depends on the details of code
generation & calling sequences I haven't looked at closely - going to
find out, though).
What makes the useage "good" is that when you include the header file
with the prototypes for the functions in a library, you get pragmas
for all the functions, too. This means that I can use the feature, and
the code will work on compilers that don't support this feature
without change. Or if they support it in another (though similar) way,
it should work.
I can't see a good way to do this without something similar to
pragmas. Wiring the names into the compiler means you can't get your
own libraries done that way (and is probably much nastier than the
above) without changing the compiler. Not good.
<mike
--
Estant assis, de nuit secrette estude, Mike Meyer
Seul, repose sur la selle d'airain, mwm@berkeley.edu
Flambe exigue, sortant de solitude, ucbvax!mwm
Fait proferer qui n'est a croire vain. mwm@ucbjade.BITNET
msb@sq.uucp (Mark Brader) (01/08/88)
On the matter of portability of programs with #pragma lines, Doug Gwyn writes: > This is not explicitly stated; rather, it is deduced ... > In fact, I used to think that the presence of #pragma "spoiled" > the code, so that no portable application could ever contain a > #pragma directive. But some other X3J11 committee members finally > convinced me that pragmas could not violate the abstract machine > semantics specified by the rest of the standard. I should note > that at least one committee member has indicated that he still > thinks the way I used to. If in fact I now have the intended, or > at least the consensual, understanding of this, then it would > probably be wise to have a discussion like the above in the > Rationale document. It seems to me that users of a Standard should not have to make deductions of such complexity that members of the Committee can get them wrong. This matter should be clarified right in the Standard, even if it does create some redundancy, or at the most in a footnote, and not tucked away in the Rationale. Mark Brader "C takes the point of view SoftQuad Inc., Toronto that the programmer is always right" utzoo!sq!msb, msb@sq.com -- Michael DeCorte
dhesi@bsu-cs.UUCP (Rahul Dhesi) (01/08/88)
In article <6939@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >In article <1766@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: >>This may not get fixed until a missile is >>actually lost in space due to a misspelled pragma. > >Since a #pragma is not supposed to change the abstract "virtual >machine" operation, it's hard to see how this could happen. Consider: If the programmer used a #pragma at all, he was probably trying to cause some detectable change in the compilation or execution of a program. Perhaps one would use a pragma to tell a compiler to use 32-bit pointers (say on an 8086 architecture), thus allowing a data-structure created at runtime, holding coordinates of Soviet missile stations, to grow to a reasonable limit. Or ask the compiler to optimize a routine by unrolling an inner loop so it runs fast enough to keep up with an anticipated salvo of Soviet missiles, so that one's Star Wars defense system might work. The point being that semantically equivalent virtual machines could still be remarkably different in speed and memory capabilities. And in a critical application, an unrecognized pragma might make all the difference. -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi
barmar@think.COM (Barry Margolin) (01/08/88)
In article <6920@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >The main reason #pragma is not suitable for "noalias" is, as I showed >in an earlier posting, the "noalias" property has potentially visible >and important effect on the computation, depending on the code. Such >code is "illegal", under the "noalias" approach, but it would have to >be permitted if #pragma were used. A #pragma is not supposed to >change the interpretation of the virtual-machine semantics of the code. >At least, that's my interpretation of what's going on here. That's not my interpretation of noalias. Noalias is merely a way to point out a potential optimization. Since a compiler that doesn't know how to perform this optimization could validly ignore noalias declarations, it cannot affect the semantics of the code. Any program tha behaves differently depending on whether a variable was declared with noalias has a bug. The standard doesn't specify the virtual-machine semantics of broken programs, only correct programs. Barry Margolin Thinking Machines Corp. barmar@think.com uunet!think!barmar
flaps@dgp.toronto.edu (Alan J Rosenthal) (01/08/88)
Let's be careful not to turn this into a flame war, please, but in a recent article ok@quintus.UUCP (Richard A. O'Keefe) writes: >Passing #pragmas through to the compiler means that >(1) /lib/cpp has to parse stuff which is significant to the C > compiler, and ONLY to the C compiler. Not 'parse', just 'accept lines beginning with'. cpp already must include code for taking the first token of a '#' line to see if it is 'if', 'include', etc. All it has to do is if(strcmp(token,"pragma") == 0) printf("%s\n",line); ... >#line is a different case... >In fact, as your example shows, the main function of # <lino> <file> >is not to be passed through by the preprocessor, but to be generated >by the preprocessor. I have never written a # <lino> <file> in my >life, but the preprocessor has made millions for me ... Ahem, no human writes # <line> <file> lines, but plenty of programs which come before cpp do, such as yacc and lex. (In fact, this is the K&R documented use for this feature.) ... >One of the things one wants to do with a program is to analyse it... >The easiest way to hack this is > cc -E source.c | analyser >which means that your analyser doesn't have to be a preprocessor as >well as a parser! The # <line> <file> lines generated by the >preprocessor tell you ... where things came from... > >If the "pragma" construct is defined as pragma(..) in the compiler >language, then each tool has to be prepared to skip a parenthesis >balanced sequence of tokens after pragma() but can otherwise ignore >the construct. But if #pragma is a pass-through (as some quite >undocumented form) then I can't defend my tool against it, because >I don't know what the passed-through form is going to look like. But even better, if you write your cpp to take an option which causes it to eat pragmas, or to object to them, either of which (or both) would be easy to implement, it's even easier. The ANSI committee can't specify this any more than they can specify the existence of cpp or cc -E, but I would hope that good cpp writers would implement it. In any case, your "as some quite undocumented form" misses the point. The documentation of this form is part of the documentation for the (not necessarily existing) cpp, not for the C standard. ajr -- "Bill Joy uses EMACS." - D. Hugh Redelmeier
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/08/88)
In article <14460@think.UUCP> barmar@sauron.think.com.UUCP (Barry Margolin) writes: >Any program >tha behaves differently depending on whether a variable was declared >with noalias has a bug. Yes, but my point was that is not true if you replace "noalias" with "pragma". It must behave the same (so far as the virtual machine is concerned) regardless of the pragma. Therefore no pragma can replace "noalias", since I've shown that some code can be rendered "buggy" simply by adding "noalias" at the [in]appropriate spots. This is a demonstration of the point, not a recommended practice!
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/08/88)
In article <1797@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: >The point being that semantically equivalent virtual machines could >still be remarkably different in speed and memory capabilities. Well, yes, but I would expect that since the software presumably passed testing, it would be adequate. Nothing unexpected should sudden crop up at run time that wouldn't also be a problem for things besides pragmas. (If this occurred, it would indicate that some section of the code had not been adequately tested.) Besides, those missiles will be using Ada anyway, so the DoD says. What a joke.
msf@amelia.nas.nasa.gov (Michael S. Fischbein) (01/08/88)
In article <6985@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >Besides, those missiles will be using Ada anyway, so the DoD says. >What a joke. Yes, Doug, it's very Jovial. mike -- Michael Fischbein msf@prandtl.nas.nasa.gov ...!seismo!decuac!csmunix!icase!msf These are my opinions and not necessarily official views of any organization.
nevin1@ihlpf.ATT.COM (00704A-Liber) (01/09/88)
In article <14460@think.UUCP> barmar@sauron.think.com.UUCP (Barry Margolin) writes: >[some stuff deleted]. Any program >that behaves differently depending on whether a variable was declared >with noalias has a bug. The standard doesn't specify the >virtual-machine semantics of broken programs, only correct programs. I agree. However, suppose I compile a program that uses 'noalias' with a compiler that ignores 'noalias'. I test it and find no problems. I now have a program which I believe works but if ported to a compiler which uses 'noalias' it might develop a bug. I believe that all programs which will conform to the ANSI C standard should run equivalently under all compilers that conform to ANSI C. (I do not believe that ANSI requires a compiler writer to implement the optimizations that can be made with the use of noalias.) With noalias, this cannot be assured. -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
chris@mimsy.UUCP (Chris Torek) (01/09/88)
[Now this is odd. I, who am quite opposed to noalias, find myself shooting at an argument against it:] In article <3313@ihlpf.ATT.COM> nevin1@ihlpf.ATT.COM (00704A-Liber) writes: >... suppose I compile a program that uses 'noalias' with a compiler that >ignores 'noalias'. I test it and find no problems. I now have a program >which I believe works but if ported to a compiler which uses 'noalias' >it might develop a bug. Unfortunately, this argument (which I myself used, after a fashion) fails in general, for there are any number of things you can do to produce code that, while incorrect, still works on some particular architecture. I think the two best arguments against noalias are 0) it is late to be adding keywords and 1) it does little for a good compiler. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 ????) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/09/88)
In article <10110@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >I think the two best arguments against noalias are 0) it is late >to be adding keywords and 1) it does little for a good compiler. 0) I think the fact that "noalias" appeared as a keyword came as a shock, which helps explain some of the initial reaction against it. However, supposing that it really did address a serious need (which is a matter of opinion), another type qualifier is clearly the best way to add the capability. 1) To the contrary, I think "noalias" will always be ignored by a poor compiler but will be exploited to the max by a good one. It allows use of vector instructions under some common circumstances, for example.
barmar@think.COM (Barry Margolin) (01/12/88)
In article <3313@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704A-Liber,N.) writes: >I agree. However, suppose I compile a program that uses 'noalias' with a >compiler that ignores 'noalias'. I test it and find no problems. I now have a >program which I believe works but if ported to a compiler which uses 'noalias' >it might develop a bug. Suppose I compile a program that uses 36-bit numbers on a machine with 36-bit words. I test it and find no problems. I now have a program which I believe works but if ported to a machine with 32-bit words it might develop a bug. >I believe that all programs which will conform to the ANSI C standard should >run equivalently under all compilers that conform to ANSI C. (I do not believe >that ANSI requires a compiler writer to implement the optimizations that can be >made with the use of noalias.) With noalias, this cannot be assured. A program which declares a variable as 'noalias' and then makes use of multiple handles to the variable in such a way that it matters whether 'noalias' is recognized does not "conform to the ANSI C standard", so you shouldn't expect it to run equivalently. You can't expect an invalid program to exhibit the same bug in all implementations, because the standard only specifies the behavior of valid programs. Barry Margolin Thinking Machines Corp. barmar@think.com uunet!think!barmar
nevin1@ihlpf.ATT.COM (00704A-Liber) (01/12/88)
In article <10110@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >In article <3313@ihlpf.ATT.COM> nevin1@ihlpf.ATT.COM (00704A-Liber) writes: >>... suppose I compile a program that uses 'noalias' with a compiler that >>ignores 'noalias'. I test it and find no problems. I now have a program >>which I believe works but if ported to a compiler which uses 'noalias' >>it might develop a bug. > >Unfortunately, this argument (which I myself used, after a fashion) >fails in general, for there are any number of things you can do to >produce code that, while incorrect, still works on some particular >architecture. Here is an situation where the same architecture is used: While I'm developing code, I don't turn the optimizing option of my compiler on. I test it and find no problems. I then turn the optimizer on. Now I find problems. (And will a debugger such as sdb be able to support 'noalias' so that I can find the bugs in my optimized code?) In order to make sure I have ANSI (so-called :-)) C compatibility, I MUST TEST optimized code (optimized with respect to noalias, that is). >>I believe that all programs which will conform to the ANSI C standard should >>run equivalently under all compilers that conform to ANSI C. (I do not >>believe that ANSI requires a compiler writer to implement the optimizations >>that can be made with the use of noalias.) With noalias, this cannot be >>assured. I still believe this. (BTW, although I am against honoring parens, my argument works FOR adding it to the language.) -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
franka@mmintl.UUCP (Frank Adams) (01/14/88)
In article <3313@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704A-Liber,N.) writes: >I believe that all programs which will conform to the ANSI C standard >should run equivalently under all compilers that conform to ANSI C. With >noalias, this cannot be assured. Not a chance in the world! If someone writes a program which assumes 32 bit ints, it will run (correctly) on some machines with some compilers, and not on other machines with other compilers. This is exactly like writing a program which uses the noalias keyword incorrectly. All *correct* conforming programs should run equivalently under all conforming compilers. But there is always the possibility of an undetected incorrectness. -- Frank Adams ihnp4!philabs!pwa-b!mmintl!franka Ashton-Tate 52 Oakland Ave North E. Hartford, CT 06108
hydrovax@nmtsun.nmt.edu (M. Warner Losh) (01/14/88)
In article <3333@ihlpf.ATT.COM>, nevin1@ihlpf.ATT.COM (00704A-Liber) writes: >While I'm developing code, I don't turn the optimizing option of my compiler >on. I test it and find no problems. I then turn the optimizer on. Now I >find problems. (And will a debugger such as sdb be able to support >'noalias' so that I can find the bugs in my optimized code?) The whole purpose of optimization should be to produce equvalent programs that execute either faster, or with less memory requirements. The noalias stuff sounds like it is agains the spirit of such an endevor, because if used incorrectly, can cause bugs. Hard to find bugs at that. Overuse of the "register" class of variables doesn't break programs when it is added (unless you happen to have a brain dead optimizer :-)) The noalias stuff, however, can cause bugs that are a real b**** to find, since ALMOST ALL DEBUGGERS don't support OPTIMIZED code, if the optimization is reaaly extensive. Having just finished a compiler's course, I know that many optimization techniques lead to code that in no way resembles the original code. There are ways around these problems, however, since if you are VERY VERY careful about how you traverse your data structures, you can avoid MOST (but not all) of these bitfalls. Noalias, from a compiler writer's point of view, would be a wonderful boon. You could now make assumptions about when varaibles change (or don't change) more easily than you could before. I'm not sure that these few advantages (in terms of a couple of instructions saved) would be worth the pain it would put the USER of the compiler through when he misuses this feature. I'm not necessarily talking about the initial writing of the code.Most people who would use the noalias feature would know what is going on. The real problem occurs in the maintance cycle of the program's life. Most of the software gets maintained by the less experienced, less knowladgeable programmers (especially after the person who originally wrote it leaves the company). These programmers more than likely might make a fix that aliased somehting that was declared as noalias (maybe a global in a .h file where the definition is "hidden" from them. Hidden in the sence that the definition is not staring them in the face every time they pop into the editor to work on the module. This feature, in my option, would be a dangerous one to have around. If you need to produce highly optimized code for a small program (<10k lines), then this would be great. If you need to maintain a large program (>1M lines), then noalias would lead to lots of time lost to finding obscure bugs in only the OPTIMIZED version of the code. In fact, many people might just turn off all optimization when they discover bugs like this, thus defeating the whole purpose of the noalias modifier in the first place. One last note : the amount of existing code that this feature break is probably very small. I too would like to see some hard data to support this claim. And sorry to have rambled for so long. -- bitnet: lush@nmt.csnet M. Warner Losh csnet: warner%hydrovax@nmtsun uucp: ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!warner%hydrovax ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!hydrovax Warning: Hydrovax is both a machine, and an account, so be careful.
chris@mimsy.UUCP (Chris Torek) (01/19/88)
In article <1227@nmtsun.nmt.edu> hydrovax@nmtsun.nmt.edu (M. Warner Losh) writes: >... many optimization techniques lead to code that in no way resembles >the original code. (There is some interesting research on debugging optimised code, by leaving enough information for the debugger to `undo' optimisations when showing state. [Just wanted to mention it.]) > Noalias, from a compiler writer's point of view, would be a wonderful >boon. ... The real problem occurs in the maintance cycle of the >program's life. This is the most basic reason I oppose `noalias', although I believe there are any number of other good reasons for it not to be in the C standard. (On the other hand, I also believe prototypes should not be in the standard, so what does that prove...?) The compiler writer could receive a yet greater boon by having all those annoying *users* write assembly code instead. Where do you draw the line? I think it should be with `noalias' outside the standard. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
chip@ateng.UUCP (Chip Salzenberg) (01/22/88)
In article <1227@nmtsun.nmt.edu> hydrovax@nmtsun.nmt.edu (M. Warner Losh) writes: >The noalias stuff sounds like it is agains the spirit of such an endevor, >because if used incorrectly, can cause bugs. Cars, when used incorrectly, kill people. You want to give up driving? -- Chip Salzenberg UUCP: "{codas,uunet}!ateng!chip" A T Engineering My employer's opinions are a trade secret. "Anything that works is better than anything that doesn't."