clang-format 14嵌套结构体指定初始化字段对齐异常问题咨询
问题
使用Ubuntu下clang-format 14.0.0-1ubuntu1版本,基于Microsoft风格配置格式化C结构体指定初始化代码时,嵌套字段related_nodes下的第一个成员.parent对齐异常,实际输出与期望输出不符。尝试用()替换{}能修复对齐,但该写法不符合C语法规范。请问这是clang-format 14的bug,还是需要调整配置文件?
实际格式化输出
pending_branches.push_back(tree_node{ .curve_params{.inertia = node.curve_params.inertia, .path_length = node.curve_params.path_length, .v_0 = seed.v_0 / 2.0f, .r_0 = seed.r_0, .scaling_factor = 0.125f * node.curve_params.scaling_factor}, .related_nodes{ .parent = parent, .younger_sibling = younger_sibling, .older_sibling = older_sibling }, .level = node.level + 1 });
期望格式化输出
pending_branches.push_back(tree_node{ .curve_params{.inertia = node.curve_params.inertia, .path_length = node.curve_params.path_length, .v_0 = seed.v_0 / 2.0f, .r_0 = seed.r_0, .scaling_factor = 0.125f * node.curve_params.scaling_factor}, .related_nodes{.parent = parent, .younger_sibling = younger_sibling, .older_sibling = older_sibling}, .level = node.level + 1 });
使用的clang-format配置
--- Language: Cpp BasedOnStyle: Microsoft AccessModifierOffset: -2 AlignAfterOpenBracket: Align AlignArrayOfStructures: Right AlignConsecutiveAssignments: true AlignConsecutiveBitFields: true AlignConsecutiveDeclarations: false AlignConsecutiveMacros: true AlignEscapedNewlines: Right AlignOperands: AlignAfterOperator AlignTrailingComments: false AllowAllArgumentsOnNextLine: false AllowAllParametersOfDeclarationOnNextLine: false AllowShortEnumsOnASingleLine: true AllowShortBlocksOnASingleLine: Always AllowShortFunctionsOnASingleLine: All AllowShortCaseLabelsOnASingleLine: true AllowShortLambdasOnASingleLine: None AllowShortIfStatementsOnASingleLine: WithoutElse AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: MultiLine BinPackArguments: false BinPackParameters: false BitFieldColonSpacing: After BreakBeforeBraces: Custom BraceWrapping: AfterCaseLabel: true AfterClass: true AfterControlStatement: Always AfterEnum: true AfterFunction: true AfterNamespace: true AfterStruct: true AfterUnion: true AfterExternBlock: true BeforeCatch: true BeforeElse: true BeforeLambdaBody: true BeforeWhile: true IndentBraces: false SplitEmptyFunction: false SplitEmptyRecord: false SplitEmptyNamespace: false BreakBeforeBinaryOperators: All BreakBeforeConceptDeclarations: true BreakBeforeTernaryOperators: false BreakBeforeInheritanceComma: true BreakInheritanceList: BeforeColon BreakConstructorInitializersBeforeComma: true BreakConstructorInitializers: BeforeColon BreakStringLiterals: false ColumnLimit: 100 QualifierAlignment: Right CompactNamespaces: false ConstructorInitializerIndentWidth: 5 ContinuationIndentWidth: 5 EmptyLineAfterAccessModifier: Never EmptyLineBeforeAccessModifier: LogicalBlock PackConstructorInitializers: CurrentLine #BasedOnStyle: '' AllowAllConstructorInitializersOnNextLine: true IncludeCategories: - Regex: '<[[:alnum:]_]+>' Priority: 3 CaseSensitive: false - Regex: '<[[:alnum:]. Priority: 2 CaseSensitive: false - Regex: '".' Priority: 1 CaseSensitive: false IncludeBlocks: Regroup IncludeIsMainRegex: '(\.test)?$' IndentAccessModifiers: false IndentWidth: 3 IndentCaseLabels: true IndentCaseBlocks: false IndentGotoLabels: false IndentPPDirectives: BeforeHash IndentExternBlock: AfterExternBlock IndentRequires: false NamespaceIndentation: Inner IndentWrappedFunctionNames: false LambdaBodyIndentation: Signature KeepEmptyLinesAtTheStartOfBlocks: false MaxEmptyLinesToKeep: 2 PointerAlignment: Left PPIndentWidth: -1 ReferenceAlignment: Pointer ReflowComments: true SeparateDefinitionBlocks: Always ShortNamespaceLines: 1 SpaceAfterCStyleCast: false SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: false SpaceBeforeAssignmentOperators: true SpaceBeforeCaseColon: false SpaceBeforeCpp11BracedList: false SpaceBeforeCtorInitializerColon: false SpaceBeforeInheritanceColon: false SpaceBeforeParens: Never SpaceAroundPointerQualifiers: Default SpaceBeforeRangeBasedForLoopColon: false SpaceInEmptyBlock: false SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 2 SpacesInAngles: Never SpacesInConditionalStatement: false SpacesInContainerLiterals: false SpacesInCStyleCastParentheses: false SpacesInLineCommentPrefix: Minimum: 1 Maximum: -1 SpacesInParentheses: false SpacesInSquareBrackets: false SpaceBeforeSquareBrackets: false Standard: Latest TabWidth: 3 UseCRLF: false UseTab: ForIndentation
分析与解决
这是clang-format 14版本的已知bug——在AlignAfterOpenBracket: Align配置下,嵌套的结构体指定初始化列表会出现对齐错乱问题。clang-format 15及以上版本已修复该问题。
若无法升级版本,可尝试以下临时规避方案:
- 将
AlignAfterOpenBracket从Align改为DontAlign:此方案会改变所有括号后的对齐逻辑,可能不符合整体格式需求; - 在
related_nodes的初始化列表前添加空注释(如/* */):强制格式化工具识别正确的对齐位置,但属于临时 workaround,不够优雅。
最彻底的解决方式是升级clang-format到15或更高版本,从根源解决嵌套初始化的对齐问题。
内容的提问来源于stack exchange,提问作者user877329
相关产品推荐
相关产品推荐

