Lookup in if constexpr discarded substatement

130 views
Skip to first unread message

corenti...@gmail.com

unread,
Oct 25, 2017, 8:39:53 AM10/25/17
to ISO C++ Standard - Future Proposals
Hello.

Currently, the discarded if-constexpr sub-statements are fully parsed, including name-lookup.
Not performing name lookup, or ignoring name lookup failure within discarded statements  could help get rid of some `#ifdef` macros, improving readability and, more importantly, tooling.


void f() {
   
if constexpr(false) {
       
UndeclaredMethod();
   
}
}

I think that the discarded blocks should still be parsed and contain valid syntax.  Tooling can, for example, rename symbols within these statements, whereas it can't inspect disabled `#ifdef` blocks without re-running the processor.


While playing with an orthogonal feature, I discovered that the MSVC compiler has a keyword to disable a block of code if a particular symbol does not exist https://msdn.microsoft.com/en-us/library/x7wy9xh3.aspx  However, I believe modifying `if constexpr` semantic would be a more powerful and generic solution.


What do you think ?

Vishal Oza

unread,
Oct 25, 2017, 11:41:30 AM10/25/17
to ISO C++ Standard - Future Proposals
Tooling I agree should look in discarded if constexpr substatement but I am not sure if including if constexpr in the compilation stage is useful as if constexpr (false) could indicate a dead code path or code that is not ready to work yet. I think the if_exists could work if if constexpr supports type traits.

Myriachan

unread,
Oct 25, 2017, 6:51:46 PM10/25/17
to ISO C++ Standard - Future Proposals
Parsing C++ at all requires knowing whether each identifier is a type, template, or other.  That's why the "typename" and "template" keywords can be required for identifiers that don't obviously depend on a template parameter.

Melissa

Arthur O'Dwyer

unread,
Oct 26, 2017, 7:11:51 PM10/26/17
to ISO C++ Standard - Future Proposals
On Wednesday, October 25, 2017 at 5:39:53 AM UTC-7, Corentin wrote:
I think this is initially attractive... but you can't say just "don't do name lookup." As Myriachan points out, something like name-lookup is required in order to figure out whether a line of tokens has "valid syntax". For example:

    foo * bar ;

could be ill-formed, or a variable definition, or a multiplication expression-statement, depending on the "part of speech" of foo and bar respectively, which can be determined by name-lookup or else by the compiler picking a "plausible default" (which is what it does in uninstantiated templates). The "plausible default" here is that both names are assumed to be values/variables, and if you want them to be typenames you must put the keyword "typename" in front of the qualified name.
The reason we don't have to litter our templates with "typename" keywords is because the compiler generally does full name lookup on every name that is not "dependent" on any template parameter. So for example

    template<class T>
    void foo() {
        using A = typename bar<T>::baz;  // OK only with "typename"
        using B = bar<int>::baz;  // OK without "typename"
    }

because bar<T>::baz is "dependent" on template parameter T, whereas bar<int>::baz is not "dependent" on anything.

But in the case of `if constexpr (false)`, what would constitute a "dependent" construct? There are no parameters to `if constexpr (false)` for anything to "depend" on. And we don't want to make every construct "dependent" because then we'd have to write "typename" and "template" keywords all over the place just to get anything to compile at all, which would be awful — much worse than the status quo.

So what would you want the new behavior of `if constexpr (false)` to be, then? Can you draw any parallels to anything in the existing C++ language?

HTH,
Arthur

Corentin

unread,
Oct 27, 2017, 3:18:25 AM10/27/17
to ISO C++ Standard - Future Proposals
Thank you both for this feedback

I'm not sure exactly how that can be resolved.
The discarded statements should "not be always ill-formed", if that make sense.  The idea is to avoid "token soup" ( expression stolen from someone on Slack ), that may occur if we simply do not parse the discarded statement.
A case could be made in favor of token soup ( it would allow the code to compile on older or not conforming compilers ), but my feeling is tat it would do more harm than good. 

So, the construct would need to be syntactically correct in some circumstances which should remain unchanged for the whole discarded statement. Writing that sentence, I realize the difficulty if implementing it and I must admit I'm not sure how that would be implemented or worded. 
However, it think a good assumption would be to assume that unknown names are either types or functions.
Global variables use are hopefully rare enough and could be marked extern, which is probably nicer and less error-prone that littering everything with typename, as you say.


Corentin

Nicol Bolas

unread,
Oct 27, 2017, 10:45:24 AM10/27/17
to ISO C++ Standard - Future Proposals
On Friday, October 27, 2017 at 3:18:25 AM UTC-4, Corentin wrote:
Thank you both for this feedback

I'm not sure exactly how that can be resolved.
The discarded statements should "not be always ill-formed", if that make sense.  The idea is to avoid "token soup" ( expression stolen from someone on Slack ), that may occur if we simply do not parse the discarded statement.
A case could be made in favor of token soup ( it would allow the code to compile on older or not conforming compilers ), but my feeling is tat it would do more harm than good. 

So, the construct would need to be syntactically correct in some circumstances which should remain unchanged for the whole discarded statement. Writing that sentence, I realize the difficulty if implementing it and I must admit I'm not sure how that would be implemented or worded. 
However, it think a good assumption would be to assume that unknown names are either types or functions.
Global variables use are hopefully rare enough and could be marked extern, which is probably nicer and less error-prone that littering everything with typename, as you say.

I don't think it's worthwhile to create heuristics to make this possible. It's not really any less "token soup" if you use heuristics to arbitrarily assign meaning to tokens without actually checking.

`if constexpr` is not meant to be a replacement for `#ifdef`.


Reply all
Reply to author
Forward
Message has been deleted
0 new messages