We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I am writing a header file with a series of #define statements, and since I use the '(' & ')' to surround many-many things, I comment these parenthesis pairings to ensure the correct matching set with some "ASCII Art" as seen below.
Using the Keil ARM IDE, I was getting funny/odd behavior where I had to re-define a #define value twice (redundantly redundant) before it 'found' the value...
// // ____________________________________________ // / __________________________________________ \ // / / ____ ________________________________ \ \ // / / / \ / \ \ \ #define SFR_T1_BASE_ADDR (*( (vu32 *) ( SFR_T1_BASE ) ) ) #define SFR_T1_BASE_ADDR (*( (vu32 *) ( SFR_T1_BASE ) ) ) #define SFR_T1_CR1 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CR1 ) ) ) #define SFR_T1_CR2 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CR2 ) ) ) #define SFR_T1_SMCR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_SMCR ) ) ) #define SFR_T1_DIER (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_DIER ) ) ) #define SFR_T1_SR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_SR ) ) ) #define SFR_T1_EGR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_EGR ) ) ) #define SFR_T1_CCMR1 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCMR1 ) ) ) #define SFR_T1_CCMR2 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCMR2 ) ) ) #define SFR_T1_CCER (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCER ) ) ) #define SFR_T1_CNT (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CNT ) ) ) #define SFR_T1_PSC (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_PSC ) ) ) #define SFR_T1_ARR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_ARR ) ) ) #define SFR_T1_RCR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_RCR ) ) ) #define SFR_T1_CCR1 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCR1 ) ) ) #define SFR_T1_CCR2 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCR2 ) ) ) #define SFR_T1_CCR3 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCR3 ) ) ) #define SFR_T1_CCR4 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCR4 ) ) ) #define SFR_T1_BDTR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_BDTR ) ) ) #define SFR_T1_DCR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_DCR ) ) ) #define SFR_T1_DMAR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_DMAR ) ) )
But after doing this ASCII art of 'comments pairing' on other #defines, I figured out why I had to double-up on (in this example) the SFR_T1_BASE_ADDR' value.
The '\' line continuation character in my 'ASCII art' was actually continuing the per-line "//" commenting so now this art looks like this... (and isn't as "pretty" as the above example either):
// // // ____________________________________________ // / __________________________________________ \ // / / ____ ________________________________ \ \ // / / / \ / \ \ \ // | | | | | | | | #define SFR_T1_BASE_ADDR (*( (vu32 *) ( SFR_T1_BASE ) ) ) #define SFR_T1_CR1 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CR1 ) ) ) #define SFR_T1_CR2 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CR2 ) ) ) #define SFR_T1_SMCR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_SMCR ) ) ) #define SFR_T1_DIER (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_DIER ) ) ) #define SFR_T1_SR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_SR ) ) ) #define SFR_T1_EGR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_EGR ) ) ) #define SFR_T1_CCMR1 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCMR1 ) ) ) #define SFR_T1_CCMR2 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCMR2 ) ) ) #define SFR_T1_CCER (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCER ) ) ) #define SFR_T1_CNT (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CNT ) ) ) #define SFR_T1_PSC (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_PSC ) ) ) #define SFR_T1_ARR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_ARR ) ) ) #define SFR_T1_RCR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_RCR ) ) ) #define SFR_T1_CCR1 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCR1 ) ) ) #define SFR_T1_CCR2 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCR2 ) ) ) #define SFR_T1_CCR3 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCR3 ) ) ) #define SFR_T1_CCR4 (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_CCR4 ) ) ) #define SFR_T1_BDTR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_BDTR ) ) ) #define SFR_T1_DCR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_DCR ) ) ) #define SFR_T1_DMAR (*( (vu32 *) ( SFR_T1_BASE + OFFSET_TIMx_DMAR ) ) )
I didn't know that it was ANSI standard for the '\' continuation to continue the double-slash "\\" per-line commenting.
I've always thought of the // scope as being a comment until the End-of-Line marker(s) (either the LF or LF+CR pair) has been reached... and was not continuable
Is this an error in the Keil IDE, or is this an error in my understanding of the "//" comment usage?
If it IS allowed to continue via the '\' character, then what is the point of using it versus the standard /* comment block */ ?
// This is a stupid example \ of a comment block which \ uses the non slash-asterisk \ asterisk-slash combination \ and it is allowed in Keil's \ <-- continue back-slash IDE "C/C++" compiler! <--- treats this as a comment due to the above '\' character.
Help me get clarification on this! (My 'ego troubles' are on edge)
--Cpt. Vince Foster 2nd Cannon Place Fort Marcy Park, VA
p.s. When using the < pre > and < b > for showing 'code' in red, the underscore ('_') character doesn't show up in this forum.
The standard comes to the rescue, and I mean the C99 standard. The examples for the 'Comments' section (6.4.9) state that:
//\ i();
is a two-line comment. Even more interesting:
/\ \ j();
is a two-line comment too...
"I didn't know that it was ANSI standard for the '\' continuation to continue the double-slash "\\" per-line commenting."
The double-slash comment is not ANSI anyhow.
I think you should essentially think of the backslash as a "reserved" symbol, and just not mess with it! I have seen it cause a number of weird issues in various situations where its has been, shall we say, ill-advised...
I would stick to just using vertical bars.
Oops, typo. I meant
/\ / j();
is a two-line comment too..
Note that \ is defined to work with the preprocessor which does give an indication why any use of \ last on the lide can have interesting effects.
Some compilers defines that \ must be the last non-white character to be a line continuation. Some compilers considers spaces when processing the \ so a space after the \ will mean that it no longer is a line continuation. This is obviously a very problematic thing, since most users do not run their editor in a mode where white spacing is printed. And a lot of editors have a setting where trailing whitespace gets automatically removed on save.
I don't have any language standards available right now, but it is interesting if:
/\ / xxx
is treated as a continuated oneliner, since preprocessors normally converts #define(a,b) a/**/b into a b, i.e. replaces inlined comments with a space to make sure that the comment removal does not merges symbols. That was also the reason why the preprocessor got a dedicated operator for intentionally merging symbols.
Mike,
The standard comes to the rescue, and I mean the C99 standard. ... section (6.4.9) ...
Ah, got it.
So, it's not Keil's fault, it must be mine.
I'm not liking this at all... the standard must be changed.
What is the advantage that such variations in \\ usage in 6.4.9 would bestow?
Andy, The double-slash comment is not ANSI anyhow.
Wrong.
It is "anyway" ('anywho' would also have been ill-advised). You people across the pond really have to dumb it down a bit. "Anyhow" implies specific knowledge of word application, whereas 'anyway' is a catch-all word used where 'irregardless' would do just fine.
I think I get your point. The '\' key on my keyboard should have an extra stiff spring behind it; although the pipe symbol ( | ) is on the same key.
Per,
Some compilers considers spaces when processing the \ so a space after the \ will mean that it no longer is a line continuation.
I haven't tested Keil's compiler for that, as I rarely use the continuation '\' symbol. But if it does, I'll complain to them directly.
My editor will allow trailing spaces. I find that editors that do automatic processes, like saving and auto-stripping, very annoying.
I regularly use an editor macro that strips all trailing spaces: since I am a control freak, I like the fact that I get to choose to do that. (My editor also allows me to color such spaces so I can see when I have such trailing spaces---it's set to a color that is slight, so I'm not annoyed by seeing them. (CodeWright v7.5 --- "The Programmer's Editing System"... yes erik, I purchased the latest release).
And I also turn off 'auto-save' features to any application I use. I save often. When my fingers at the keyboard are idle, it is almost automatic that I key-stroke in the 'save file' process. This stems from way-back when my CP/M system would randomly crash while I was re-writing the BIOS. I never knew when the system would crash, so I got in the habit of saving my work every 30 seconds or so. (Yes, I fixed that BIOS crash problem: back in those "Z80 assembler days").
No way.
There are really no "variations" involved --- those are just some examples. It's a question of processing order. Backslash continuation is almost the first thing the preprocessor considers ("you don't want to know about trigraphs"). I.e. by the time the preprocessor considers comments, there is no longer any difference at all between
/\ *\ huh?\ */ a /\ / c\ omm\ ent
and
/*huh?*/ a // comment
[Regarding the fact that backslash only escapes a linebreak directly following it]
That complaint would be thoroughly unjustified. The definition of how line continuation works is fixed by the language standard. Keil is in no better position to ignore that definition than you are.
My interpretation of that is: because it is easier to make a tool this way than that way, the \ takes precedence, and the result is then parsed for any comment [removal] purposes.
My question on what advantage it is to have:
/\ /retarded comment construct
still stands.
I see no benefit from those 'examples' where the tool should allow half-baked commenting of the // variety.
The other examples in that section are valid and serve a purpose.
On the issue of 'continuation' ( \ ) in Section 5.2.1.2 #2, should be modified: FROM
Section 5.2.1.2 #2 Each instance of a backslash character (\) immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines. Only the last backslash on any physical source line shall be eligible for being part of such a splice. A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character before any such splicing takes place.
TO
Section 5.2.1.2 #2 Each instance of a backslash character (\) (struck out "immediately") followed by a new-line character or white-space, or a comment block (of either the /* comment */ or // comment variety) is deleted, splicing physical source lines to form logical source lines. Only the last backslash on any physical source line shall be eligible for being part of such a splice. A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character before any such splicing takes place.
This would allow end-of-line commenting on a continuation basis:
#define SOME_LONG_STRING_THING "\ // Below is the new Greeting message... Welcome to \n\ // English greeting (management wanted this) The Murmer Maker 3000\n\ // Model Name (revision &d)\n\ // Revision 1) Added GPS Capability\n\ // *new* item 1 2) Added Cell Phone\n\ // *new* item 2 3) Added AED Capability\n\ // *new* item 3 4) Removed \"Kill\" Switch\n\// (too many customer complaints) " // END OF GREETING MESSAGE STRING
Of course, now that you pointed out the specification, that a [Keil] complaint would be thoroughly unjustified, I now realize you are right on that point, and that Keil complies to the specification.
Anyway this is not a standards forum. I'll just comply with the rules.
But seriously, thanks for responding Hans. And the others too.