compiler error with preprocessing directives

C

cody

the following leads to an error (note that TEST is not defined):

#if TEST
string s = @"
#"; // <-- the error is "preprocessing directive expected"
#endif

also, here we get the same error:

#if TEST
/*
# */
#endif

iam not sure wheather this is a problem in the compiler or the spec, but in
my opinion even in such directives the compiler should parse comments and
verbatim string to ensure we can use #if statements everywhere and do not
have to change to code to make if work.
 
J

Jon Skeet [C# MVP]

cody said:
the following leads to an error (note that TEST is not defined):

#if TEST
string s = @"
#"; // <-- the error is "preprocessing directive expected"
#endif

also, here we get the same error:

#if TEST
/*
# */
#endif

iam not sure wheather this is a problem in the compiler or the spec, but in
my opinion even in such directives the compiler should parse comments and
verbatim string to ensure we can use #if statements everywhere and do not
have to change to code to make if work.

The spec disagrees:

<quote>
The remaining conditional-sections, if any, are processed as skipped-
sections: except for pre-processing directives, the source code in the
section need not adhere to the lexical grammar; no tokens are generated
from the source code in the section; and pre-processing directives in
the section must be lexically correct but are not otherwise processed.
Within a conditional-section that is being processed as a skipped-
section, any nested conditional-sections (contained in nested #if...
#endif and #region...#endregion constructs) are also processed as
skipped-sections.
</quote>

Basically, #"; isn't lexically correct as a preprocessing directive.
The comments business is interesting - I assume that's where the "no
tokens are generated" bit comes in.

Can you give an example where it's actually *useful* to have lexically
invalid preprocessor directives in your code?
 
C

cody

The remaining conditional-sections, if any, are processed as skipped-
sections: except for pre-processing directives, the source code in the
section need not adhere to the lexical grammar; no tokens are generated
from the source code in the section; and pre-processing directives in
the section must be lexically correct but are not otherwise processed.
Within a conditional-section that is being processed as a skipped-
section, any nested conditional-sections (contained in nested #if...
#endif and #region...#endregion constructs) are also processed as
skipped-sections.
</quote>

Basically, #"; isn't lexically correct as a preprocessing directive.
The comments business is interesting - I assume that's where the "no
tokens are generated" bit comes in.

Can you give an example where it's actually *useful* to have lexically
invalid preprocessor directives in your code?

Useful or not but it happened. I copied sql script from a file into my code
and used @ to make a verbatim string so that I do not have to change
something in the string and do not need to make "stuff"+ for every single
line.
The sql code contained sql comments (#) and they were located at line
beginnings.
Because this code wasn't ready for release I decided to put #if..#endif
around it.
So that was my story :)

Iam sure there are more situations where similar things might happen. imho
the best thing would be if the the compiler would ignore all # inside a #if
block unless it is the #endif directive which would really minimize the
chance that such things happen.
 
J

Jon Skeet [C# MVP]

cody said:
Useful or not but it happened. I copied sql script from a file into my code
and used @ to make a verbatim string so that I do not have to change
something in the string and do not need to make "stuff"+ for every single
line.
The sql code contained sql comments (#) and they were located at line
beginnings.
Because this code wasn't ready for release I decided to put #if..#endif
around it.
So that was my story :)

Iam sure there are more situations where similar things might happen. imho
the best thing would be if the the compiler would ignore all # inside a #if
block unless it is the #endif directive which would really minimize the
chance that such things happen.

Except it also has to look for #if so that it can match the right
number of levels of #endif.

#if isn't meant to be a way of commenting out code - do that with
multi-line comments, or get the IDE to add // at the start of each line
(I think you can just highlight the relevant section and then press a
shortcut - I don't know the key off hand.)

So, to me it sounds like changing your behaviour in this case would be
a better answer than changing the spec to suit this particular case.
 
C

cody

Iam sure there are more situations where similar things might happen.
Except it also has to look for #if so that it can match the right
number of levels of #endif.

Which it also has to do at the moment, otherwise the following wouldn't
compile:

#if false
#if false
#endif
#endif
#if isn't meant to be a way of commenting out code - do that with
multi-line comments, or get the IDE to add // at the start of each line
(I think you can just highlight the relevant section and then press a
shortcut - I don't know the key off hand.)

So, to me it sounds like changing your behaviour in this case would be
a better answer than changing the spec to suit this particular case.

I was conditionally compiling my code to that I have unfinished code only in
DEBUG mode.
 
J

Jon Skeet [C# MVP]

cody said:
Which it also has to do at the moment, otherwise the following wouldn't
compile:

#if false
#if false
#endif
#endif

That's my point - it has to validate *some* preprocessor directives, so
I don't see that it's a big problem to have to validate all
preprocessor directives.
I was conditionally compiling my code to that I have unfinished code only in
DEBUG mode.

But the code you "conditioned" out was invalid - if it had been valid
code, it would have been okay. The only exception to that is the
comment with the preprocessor directive in it - it would be reasonable
to expect that to work.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top