Discussion:
C++17 constexpr if support
Bryan St. Amour
2017-05-02 16:00:20 UTC
Permalink
Hello,

C++17 supports a new feature for expanding code conditionally at
compile-time:

int f() {
if constexpr (some-condition) {
// compile if true
}
}

Using the latest snapshot of cc-mode with emacs 24.5.1 on Windows 10,
the code gets indented as follows

if constexpr (true) {
// true case
}

i.e. the indentation level for the block is aligned with the start of
the "constexpr" keyword, instead of with the "if" keyword. Is there
anything I can do to get it to indent properly?

Regards,

Bryan St. Amour
--
Bryan St. Amour

Slackware is the answer.
What's the question?
Michael Welsh Duggan
2017-05-04 05:32:33 UTC
Permalink
Post by Bryan St. Amour
C++17 supports a new feature for expanding code conditionally at
int f() {
if constexpr (some-condition) {
// compile if true
}
}
Using the latest snapshot of cc-mode with emacs 24.5.1 on Windows 10,
the code gets indented as follows
if constexpr (true) {
// true case
}
i.e. the indentation level for the block is aligned with the start of
the "constexpr" keyword, instead of with the "if" keyword. Is there
anything I can do to get it to indent properly?
If you're handling this, C++ 17 will throw a few more curve balls at
you. "if constexpr" is syntactically easy, although it doesn't seem to
fit in a good place in the current cc-langs defintions. The "if" token
can be optionally followed by the "constexpr" token.

The "if" has also changed in that the condition in parentheses can now
have an optional init-statment:

if (int c = getchar(); c != eof) {
// 'c' is in scope here
}

This (the initializer) can also be done in the switch statement.

http://en.cppreference.com/w/cpp/language/if
http://en.cppreference.com/w/cpp/language/switch
--
Michael Welsh Duggan
(***@md5i.com)
Bryan St. Amour
2017-05-10 15:06:53 UTC
Permalink
Post by Michael Welsh Duggan
Post by Bryan St. Amour
C++17 supports a new feature for expanding code conditionally at
int f() {
if constexpr (some-condition) {
// compile if true
}
}
Using the latest snapshot of cc-mode with emacs 24.5.1 on Windows 10,
the code gets indented as follows
if constexpr (true) {
// true case
}
i.e. the indentation level for the block is aligned with the start of
the "constexpr" keyword, instead of with the "if" keyword. Is there
anything I can do to get it to indent properly?
If you're handling this, C++ 17 will throw a few more curve balls at
you. "if constexpr" is syntactically easy, although it doesn't seem to
fit in a good place in the current cc-langs defintions. The "if" token
can be optionally followed by the "constexpr" token.
The "if" has also changed in that the condition in parentheses can now
if (int c = getchar(); c != eof) {
// 'c' is in scope here
}
This (the initializer) can also be done in the switch statement.
http://en.cppreference.com/w/cpp/language/if
http://en.cppreference.com/w/cpp/language/switch
If I were to attempt to add this functionality, do you know where I
would even start? i.e. whereabouts in the CC-mode codebase would one
need to look first to make the change? I'm talking about my original
issue, adding support for conditional initializers is a totally
different bag of scorpions.
--
Bryan St. Amour

Slackware is the answer.
What's the question?
Alan Mackenzie
2017-05-10 20:37:07 UTC
Permalink
Hello again, Bryan.
Post by Bryan St. Amour
Post by Michael Welsh Duggan
Post by Bryan St. Amour
C++17 supports a new feature for expanding code conditionally at
int f() {
if constexpr (some-condition) {
// compile if true
}
}
Using the latest snapshot of cc-mode with emacs 24.5.1 on Windows 10,
the code gets indented as follows
if constexpr (true) {
// true case
}
i.e. the indentation level for the block is aligned with the start of
the "constexpr" keyword, instead of with the "if" keyword. Is there
anything I can do to get it to indent properly?
If you're handling this, C++ 17 will throw a few more curve balls at
you. "if constexpr" is syntactically easy, although it doesn't seem to
fit in a good place in the current cc-langs defintions. The "if" token
can be optionally followed by the "constexpr" token.
The "if" has also changed in that the condition in parentheses can now
if (int c = getchar(); c != eof) {
// 'c' is in scope here
}
This (the initializer) can also be done in the switch statement.
http://en.cppreference.com/w/cpp/language/if
http://en.cppreference.com/w/cpp/language/switch
If I were to attempt to add this functionality, do you know where I
would even start? i.e. whereabouts in the CC-mode codebase would one
need to look first to make the change?
The main indentation functionality is in the function
`c-guess-basic-syntax' in cc-engine.el. It's a rather long function, but
not too difficult to understand. The bit that handles "if" statements is
at "CASE 18: A substatement we can recognize by keyword." in that
function.

It's useful also to know about CC Mode's "language variables", defined in
cc-langs.el by `c-lang-defvar' and `c-lang-defconst'. These "variables"
(actually, really constants) define the languages CC Mode handles. They
allow the values for these languages to be entered in a table-based
fashion.

The fontification is done by functions in cc-fonts.el. Command handling
(things like C-M-a, and the "electric" indentation caused by typing, say,
";" are in cc-cmds.el.

The very best to you, if you decide to get into the CC Mode code base.
You're free to ask questions about it on this list.
Post by Bryan St. Amour
I'm talking about my original issue, adding support for conditional
initializers is a totally different bag of scorpions.
What a wonderful analogy. :-)
Post by Bryan St. Amour
--
Bryan St. Amour
Slackware is the answer.
What's the question?
--
Alan Mackenzie (Nuremberg, Germany).
Alan Mackenzie
2017-05-10 20:04:52 UTC
Permalink
Hello, Michael.
Post by Michael Welsh Duggan
Post by Bryan St. Amour
C++17 supports a new feature for expanding code conditionally at
int f() {
if constexpr (some-condition) {
// compile if true
}
}
Using the latest snapshot of cc-mode with emacs 24.5.1 on Windows 10,
the code gets indented as follows
if constexpr (true) {
// true case
}
i.e. the indentation level for the block is aligned with the start of
the "constexpr" keyword, instead of with the "if" keyword. Is there
anything I can do to get it to indent properly?
If you're handling this, C++ 17 will throw a few more curve balls at
you. "if constexpr" is syntactically easy, although it doesn't seem to
fit in a good place in the current cc-langs defintions. The "if" token
can be optionally followed by the "constexpr" token.
I think it would need a new c-lang-defvar (or possibly several) with the
meaning "noise keywords". This would be null in the CC Mode languages
other than C++.
Post by Michael Welsh Duggan
The "if" has also changed in that the condition in parentheses can now
if (int c = getchar(); c != eof) {
// 'c' is in scope here
}
This (the initializer) can also be done in the switch statement.
Why, oh why, do they do things like this? What was wrong with using the
comma instead of that semicolon, giving an expression which has been
syntactically and semantically valid since the early releases of C++?
Post by Michael Welsh Duggan
http://en.cppreference.com/w/cpp/language/if
http://en.cppreference.com/w/cpp/language/switch
Thanks, I know about these. :-) I'll look them up, sometime.
Post by Michael Welsh Duggan
--
Michael Welsh Duggan
--
Alan Mackenzie (Nuremberg, Germany).
John Yates
2017-05-10 21:01:25 UTC
Permalink
Post by Alan Mackenzie
Why, oh why, do they do things like this? What was wrong with using the
comma instead of that semicolon, giving an expression which has been
syntactically and semantically valid since the early releases of C++?
Because the initializer is allowed to be a declaration. And keep in mind
joys of structured bindings:

if (auto [it, inserted] = map.insert({key, valu}); !inserted) {
}

/john
Michael Welsh Duggan
2017-05-10 21:24:10 UTC
Permalink
Post by Alan Mackenzie
Hello, Michael.
[...]
Post by Alan Mackenzie
Post by Michael Welsh Duggan
The "if" has also changed in that the condition in parentheses can now
if (int c = getchar(); c != eof) {
// 'c' is in scope here
}
This (the initializer) can also be done in the switch statement.
Why, oh why, do they do things like this? What was wrong with using the
comma instead of that semicolon, giving an expression which has been
syntactically and semantically valid since the early releases of C++?
It's not that bad. Essentially if and switch have picked up part of
for's syntax. You might be able to steal some appropriate code from
there.
--
Michael Welsh Duggan
(***@cert.org)
Alan Mackenzie
2017-05-10 20:17:56 UTC
Permalink
This post might be inappropriate. Click to display it.
Loading...