7

Can I use the following in C++?:

#define $ cout

int main(){
    $<<"Hello World!\n";
    return 0;
}

I'm wondering whether it will cause any conflicts.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Somnium
  • 1,059
  • 1
  • 9
  • 34
  • 1
    It could, since dollar signs don't have to be supported. – chris Feb 19 '14 at 15:27
  • 8
    It also makes your code hard to read. – maxywb Feb 19 '14 at 15:28
  • 3
    What if you wish to print a string that contains a dollar sign? Seems like it invites far more trouble than it avoids. "Leave that kind of stuff for jQuery", would be my recommendation. – enhzflep Feb 19 '14 at 15:29
  • 4
    @enhzflep: Preprocessor directives don't touch string literals. – jwodder Feb 19 '14 at 15:30
  • I have tested it in Code::Blocks - it worked, however I don't know whether it will work in other compilers and whether it is allowed. – Somnium Feb 19 '14 at 15:30
  • @jwodder - thank-you. Never tried it, since it just seems like an invitation for trouble to me - albeit for different reasons than I'd considered. – enhzflep Feb 19 '14 at 15:32
  • 6
    Why the downvotes, the OP is asking if it is valid. I would not advocate for it but still a valid question. – Shafik Yaghmour Feb 19 '14 at 15:36
  • 1
    MSVC allows `$` in identifiers, [so do clang and g++](http://coliru.stacked-crooked.com/a/bd09aa84f4aec350). Still don't see why you'd want to do this :) – melak47 Feb 19 '14 at 15:38
  • 4
    @melak47, Everyone kept saying, "Not enough jQuery", so we're trying to add it with exact syntax to C++. – chris Feb 19 '14 at 15:40

3 Answers3

12

It's not definitively legal, but your implementation is allowed to accept it.

Consider:

[C++11: 2.5/1]: Each preprocessing token that is converted to a token (2.7) shall have the lexical form of a keyword, an identifier, a literal, an operator, or a punctuator.

Here, your $ is obviously not a keyword, operator or punctuator (as these are enumerated in the standard), and it doesn't look like a literal, so it could only be an identifier; now, identifiers must contain only alphanumerics and underscores, and digits cannot be leading (based on the grammar denoted under [C++11: 2.11]).

However, the standard does also allow implementations to accept other characters, so what you want to do may work, but it will not be portable.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 2
    Actually to be more precise the grammar does allow for *implementation-defined characters*. – Shafik Yaghmour Feb 19 '14 at 16:09
  • Please provide a link to the information you are referencing, for others to use. Even though a quick search on the Internet will turn it up, it would improve your answer quality. – Michael J. Gray Feb 19 '14 at 16:09
  • 5
    @MichaelJ.Gray: It is not possible to hyperlink to the C++ standard. The only reference required is the name of the standard ("C++11" being an abbreviation) and the paragraph number within that document. I could link to the last pre-C++11 working draft PDF in all of my answers but I really don't think that's in the scope of them. Readers are welcome to look up the reference material if they desire, using their own cunning and mental prowess, much as you would walk to a library to find a scientific paper cited in the same way. – Lightness Races in Orbit Feb 19 '14 at 16:56
  • 1
    @ShafikYaghmour: Aha, you're absolutely right! I have edited that in. Thanks. – Lightness Races in Orbit Feb 19 '14 at 17:00
  • 1
    No, a `$` can be a leading character, since it can be a an *identifier-nondigit*. – Keith Thompson Feb 19 '14 at 17:02
  • @KeithThompson: Right yes that's also true :) All fixes now applied. – Lightness Races in Orbit Feb 19 '14 at 17:02
  • @KeithThompson What I have received from your explanation is that you do not feel like providing a URL because libraries and Google exist. I never said anything was "required" as you seem to believe. I was simply indicating it would be useful and improve the quality of your answer; nothing more. I doubt you happen to have something physically in your hand that you have referenced, so it would be nice to see what you are reading and where you retrieved your information from specifically. That's all. – Michael J. Gray Feb 19 '14 at 17:04
  • @MichaelJ.Gray: The quoted passage is taken from the ISO/IEC 14882 C++ standard third edition ("C++11"). This is denoted in the answer. It is not a web reference. Not all references must be web links. Other scholarly resources exist in the world. In this case, as I have already indicated in my previous comment, it is not possible to link to the real standard even if I thought it was appropriate or would actually enhance my answers, which I do not. Still, I appreciate your opinion and input. (And your doubt is close to wrong -- the C++ standard is in PDF format on my hard drive.) – Lightness Races in Orbit Feb 19 '14 at 17:05
  • @MichaelJ.Gray: Finally, I am not called Keith. – Lightness Races in Orbit Feb 19 '14 at 17:07
  • 1
    I doubt this link would be helpful http://www.iso.org/iso/catalogue_detail.htm?csnumber=50372 – R. Martinho Fernandes Feb 19 '14 at 17:12
  • @R.MartinhoFernandes: Yeah it's nice to know what it'll take to _get_ the PDF onto your hard drive, I suppose... – Lightness Races in Orbit Feb 19 '14 at 17:14
  • 1
    @R.MartinhoFernandes: No, but a link to [a standard draft](http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3242.pdf) would be. (I'm not sure whether N3242 is the best version to refer to.) – Keith Thompson Feb 19 '14 at 17:14
  • 1
    @KeithThompson: I already addressed that. I won't link to a document that is not precisely the document referenced, just to appease lovers of web hyperlinks. International standards documents can be looked up on demand just like any other formal reference text. It actually borders on a matter of principle, to me: this isn't the same as quoting some web tutorial or video presentation; the name of the standard _is_ the hyperlink. I'm certainly not going to start linking to standard drafts on all 3,000 standard-referencing answers; my, what a lot of dead links that'd one day be! – Lightness Races in Orbit Feb 19 '14 at 17:14
  • @LightnessRacesinOrbit: Then we disagree. The actual standard costs money, and is not worth it for most programmers. The drafts are close enough for almost all purposes. I'm more familiar with C; I've bought copies of all 3 editions of the standard, but I refer to N1256 and N1570 more often. A link to a (carefully selected) draft would IMHO improve your answer. (FWIW, I don't feel strongly enough about it to give in to the temptation to edit a link into your answer.) – Keith Thompson Feb 19 '14 at 17:19
  • @KeithThompson: If some reader wants to look up this passage in a draft standard document, they are more than welcome to. For serious developers, they can look it up in their copy of the standard. That's a choice each reader can make for themselves; I'm not going to start hand-holding by appointing myself an indexing service for international standard documents. I do not agree whatsoever that it would improve my answer: it would only introduce the potential for link rot and contribute to the growing epidemic of _lack of ability to perform research_. Everyone wants everything done for them >. – Lightness Races in Orbit Feb 19 '14 at 17:26
  • If you expect readers to look up the passage either in a draft or in the actual standard, you might consider linking to [the committee site](http://www.open-std.org/JTC1/SC22/WG21/). – Keith Thompson Feb 19 '14 at 17:27
  • @KeithThompson: Again, I do not consider that to be in the scope of my answer which, to apply slippery-slope logic to your suggestion, might as well have a paragraph explaining what C++ is while I'm at it. It's clear that I am not going to be able to persuade you how to properly cite international standards (and this is an entirely conventional and widespread way to do so, both on SO, in academia and in industry) so I shall suggest that we simply agree to disagree at this juncture. :) – Lightness Races in Orbit Feb 19 '14 at 17:28
  • [Honestly, I don't expect anyone to look up anything — I already quoted the relevant text. :)] – Lightness Races in Orbit Feb 19 '14 at 17:36
  • @KeithThompson My sincerest apologies for accidentally tagging you when intending to tag "Lightness Races in Orbit", earlier. – Michael J. Gray Feb 19 '14 at 21:03
5

This is implementation defined behavior. $ is not included in grammar for an identifiers the rules for identifier names in C++ are:

  1. It can not start with a number
  2. Can be composed of letters, numbers, underscore, universal character names and implementation defined characters
  3. Can not be a keyword.

But it does allow for implementation-defined characters which many compilers support as an extension, including gcc and Visual Studio.

The actual grammar is covered in the draft C++ standard section 2.11 Indentifier:

identifier:
  identifier-nondigit            <- Can only start with a non-digit
  identifier identifier-nondigit <- Next two rules allows for subsequent 
  identifier digit               <-  characters to be those outlined in 2 above
identifier-nondigit:
  nondigit                       <- a-z, A-Z and _ 
  universal-character-name
  other implementation-defined characters
[...]

We can see this applies to define from section 16 Preprocessing directives. We can see from the grammar that it must be an identifier:

# define identifier replacement-list new-line
# define identifier lparen identifier-listopt) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list, ... ) replacement-list new-line
         ^^^^^^^^^^
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • 4
    Also worth mentioning, MSVC has an extension for bananas, too! https://dl.dropboxusercontent.com/u/247271563/intelliBananas.png – melak47 Feb 19 '14 at 15:44
  • @melak47 that falls under *universal-character-name* as far as I know and so would be an extension. – Shafik Yaghmour Feb 21 '14 at 13:54
0

There is a funny situation with some compilers that allow to use $ in identifiers. For example at least MS VC++ 2010 allows to use $ in identifiers.

So if for example you defined

char $ = '$';

and then wrote

#define $ std::cout
//...

$ << $;

then instead of symbol $ you will see in the console output number 1 or some integer number.:)

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 1
    @PlasmaHH Old Borland compiler outputed 1 instead of the real address of std::cout. The Standard does not define whar value shall be returned for std::cout when it is converted to void pointer. – Vlad from Moscow Feb 19 '14 at 15:47
  • @PlasmaHH Well, of course you get the same as with `&std::cout`; the line `$ << $;` expands to `std::cout << std::cout;` after all... – cmaster - reinstate monica Feb 19 '14 at 19:54