Package: cc-mode;
Reported by: Arsen Arsenović <arsen <at> aarsen.me>
Date: Sun, 18 Aug 2024 09:52:02 UTC
Severity: normal
Done: Alan Mackenzie <acm <at> muc.de>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Arsen Arsenović <arsen <at> aarsen.me> To: 72695 <at> debbugs.gnu.org Subject: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas Date: Sun, 18 Aug 2024 11:50:32 +0200
Package: cc-mode <#secure method=pgpmime mode=sign> Package: cc-mode Hi! CC-mode appears to misindent the following C++ snippet: void f() { auto data_printer = [] <typename T> (const T& data) { if constexpr (true) { if constexpr (std::same_as<T, std::string>) std::println (" data: \"{}\"", data); else std::println (" data: {}", data); } else std::println (""); }; if constexpr (false) { foo (); } } This example is supposed to be formatted in accordance to the default GNU style, but the 'if constexpr' in the lambda expression are misindented. This might be the case because the inline-open of the lambda gets mis-interpreted as statement-cont, so the statements in the body are indented as brace-list-intro and brace-entry-open rather than statement-block-intro and substatement-open. WRT lambda indentation generally, CC-mode appears to format lambdas in GNU style so that their '{' aligns with their '[' (i.e. aligns their compound-statement with their lambda-introducer per ISO parlance). Maybe we should consider indenting them less. For instance, that indentation leads to: std::visit ([] <typename T> (const T& data) { if constexpr (!std::same_as<T, std::monostate>) { if constexpr (std::same_as<T, std::string>) std::println (" data: \"{}\"", data); else std::println (" data: {}", data); } else std::println (""); }, tok.data); ... which is /really/ aggressive. Maybe it'd be better to do something like: std::visit ([] (args) { body }, visit-args-cont); I realize this is a bit inconsistent with the rest of the style, but given that placing the introducer (and generally function arguments) on a new line does not work in the GNU C/++ style as it does in Lisp: function_name ( arg1, arg2); ... versus: (function-name arg1 arg2) Anyway, thanks in advance! Have a most lovely day. Emacs : GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.42, cairo version 1.18.0) of 2024-08-13 Package: CC Mode 5.35.2 (C++//l) Buffer Style: gnu c-emacs-features: (pps-extended-state col-0-paren posix-char-classes gen-string-delim gen-comment-delim syntax-properties category-properties 1-bit) current state: ============== (setq c-basic-offset 2 c-comment-only-line-offset '(0 . 0) c-indent-comment-alist '((anchored-comment column . 0) (end-block space . 1) (cpp-end-block space . 2)) c-indent-comments-syntactically-p nil c-block-comment-prefix "" c-comment-prefix-regexp '((pike-mode . "//+!?\\|\\**") (awk-mode . "#+") (other . "//+\\|\\**")) c-doc-comment-style '((java-mode . javadoc) (pike-mode . autodoc) (c-mode . gtkdoc) (c++-mode . gtkdoc)) c-cleanup-list '(scope-operator) c-hanging-braces-alist '((substatement-open before after) (arglist-cont-nonempty)) c-hanging-colons-alist nil c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist) c-backslash-column 48 c-backslash-max-column 72 c-special-indent-hook '(t c-gnu-impose-minimum) c-label-minimum-indentation 1 c-offsets-alist '((inexpr-class . +) (inexpr-statement . +) (lambda-intro-cont . +) (inlambda . 0) (template-args-cont c-lineup-template-args c-lineup-template-args-indented-from-margin) (incomposition . +) (inmodule . +) (innamespace . +) (inextern-lang . +) (composition-close . 0) (module-close . 0) (namespace-close . 0) (extern-lang-close . 0) (composition-open . 0) (module-open . 0) (namespace-open . 0) (extern-lang-open . 0) (objc-method-call-cont c-lineup-ObjC-method-call-colons c-lineup-ObjC-method-call +) (objc-method-args-cont . c-lineup-ObjC-method-args) (objc-method-intro . [0]) (friend . 0) (cpp-define-intro c-lineup-cpp-define +) (cpp-macro-cont . +) (cpp-macro . [0]) (inclass . +) (stream-op . c-lineup-streamop) (arglist-cont-nonempty c-lineup-gcc-asm-reg c-lineup-arglist) (arglist-cont c-lineup-gcc-asm-reg 0) (comment-intro c-lineup-knr-region-comment c-lineup-comment) (catch-clause . 0) (else-clause . 0) (do-while-closure . 0) (access-label . -) (case-label . 0) (substatement . +) (statement-case-intro . +) (statement . 0) (brace-entry-open . 0) (brace-list-entry . 0) (brace-list-close . 0) (block-close . 0) (block-open . 0) (inher-cont . c-lineup-multi-inher) (inher-intro . +) (member-init-cont . c-lineup-multi-inher) (member-init-intro . +) (annotation-var-cont . +) (annotation-top-cont . 0) (constraint-cont . +) (topmost-intro . 0) (knr-argdecl . 0) (func-decl-cont . +) (inline-close . 0) (class-close . 0) (class-open . 0) (defun-block-intro . +) (defun-close . 0) (defun-open . 0) (c . c-lineup-C-comments) (string . c-lineup-dont-change) (topmost-intro-cont first c-lineup-topmost-intro-cont c-lineup-gnu-DEFUN-intro-cont) (brace-list-intro first c-lineup-2nd-brace-entry-in-arglist c-lineup-class-decl-init-+ +) (brace-list-open . +) (inline-open . 0) (arglist-close . c-lineup-arglist) (arglist-intro . c-lineup-arglist-intro-after-paren) (statement-cont . +) (statement-case-open . +) (label . 0) (substatement-label . 0) (substatement-open . +) (knr-argdecl-intro . 5) (statement-block-intro . +) ) c-buffer-is-cc-mode 'c++-mode c-tab-always-indent t c-syntactic-indentation t c-syntactic-indentation-in-macros t c-ignore-auto-fill '(string cpp code) c-auto-align-backslashes t c-backspace-function 'backward-delete-char-untabify c-delete-function 'delete-char c-electric-pound-behavior nil c-default-style '((java-mode . "java") (awk-mode . "awk") (other . "gnu")) c-enable-xemacs-performance-kludge-p nil c-old-style-variable-behavior nil defun-prompt-regexp nil tab-width 8 comment-column 32 parse-sexp-ignore-comments t parse-sexp-lookup-properties t auto-fill-function 'c-do-auto-fill comment-multi-line t comment-start-skip "\\(?://+\\|/\\*+\\)\\s *" fill-prefix nil fill-column 79 paragraph-start "[ ]*\\(//+\\|\\**\\)[ ]*$\\|^\f" adaptive-fill-mode t adaptive-fill-regexp "[ ]*\\(//+\\|\\**\\)[ ]*\\([-–!|#%;>*·•‣⁃◦ ]*\\)" ) -- Arsen Arsenović
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.