fixhunt

clang-tidy readability-redundant-parentheses

labelled unknown
Runs / 2026-10-17T20-07-51-505Z-58k4-clang-tidy-readability-redundant-parenthesesclang-tidy 24.0.0git2026-10-17 20:07 UTC8 programs × 2 round(s)16 programs, 4 fired, 4 fixed, 0 findings, 1 rejectedmodel cost $0.0029

Analysis Nemotron 3 Super

The rule flags unnecessary parentheses around expressions where they do not affect precedence or meaning.

Fix: Removes parentheses that are not required for operator precedence or to disambiguate parsing, rewriting the expression to its form without the redundant grouping.

12 hazards
  • Removing parentheses around a function-like macro invocation may change how arguments are grouped if the macro expects comma-separated parameters.
  • Stripping parentheses from a cast-expression like `(T)x` alters the cast target and may cause misinterpretation as a declaration or incorrect type conversion.
  • Eliminating parentheses around a braced-init-list such as `(T){x}` can prevent aggregate initialization and instead invoke a constructor if available.
  • Deleting parentheses in a lambda-expression like `([]{})()` may prevent it from being treated as a single postfix-expression, breaking the call.
  • Removing parentheses around a comma-expression such as `(a, b)` changes evaluation order context, potentially altering which value is used in larger expressions.
  • Taking away parentheses from a conditional-expression like `(a ? b : c)` can lead to incorrect parsing due to lower precedence of `?:`, changing the bound of the ternary.
  • Erasing parentheses around an assignment expression like `(x = y)` may prevent it from being treated as a single value in outer contexts, affecting use in conditions or function calls.
  • Stripping parentheses from a `sizeof` or `alignof` operand like `sizeof (T)` risks misparsing if followed by a declarator, turning it into an ambiguous or invalid declaration.
  • Removing parentheses around a unary operator expression such as `(!p)` can alter binding with adjacent operators, e.g., in `!p && q` vs `!(p && q)`.
  • Deleting parentheses in a pack expansion like `(Args)...` breaks the expansion syntax, causing a compile error.
  • Taking away parentheses around a dependent name in a template, such as `(typename T::type)`, may hinder lookup and break instantiation.
  • Stripping parentheses that visually group code for readability may drop associated inline comments attached to the parentheses lines, reducing code clarity.

Programs

idresulttitlehazard
r1-p001silent prediction offRedundant Parentheses Around Throw ExpressionRemoving parentheses around a throw expression changes destructors' evaluation order due to comma operator interaction.
r1-p002silent prediction offRedundant Parentheses in For Loop InitRemoving parentheses around comma-expression in for init causes iterator invalidation via premature increment.
r1-p003fix okRedundant Parentheses Around Overloaded Operator CallRemoving parentheses around user-defined conversion operator call alters side effect timing.
r1-p004silent prediction offRedundant Parentheses Around Shift ExpressionRemoving parentheses around shift expression changes overflow behavior due to precedence with addition.
r1-p005silent prediction offRedundant Parentheses Around Braced Init ListRemoving parentheses around braced-init-list selects constructor over aggregate initialization.
r1-p006silentRedundant Parentheses Around Sizeof ExpressionRemoving parentheses around sizeof operand creates ambiguous declaration when followed by pointer declarator.
r1-p007fix okRedundant Parentheses in Dependent Decltype ExpressionRemoving parentheses around decltype expression changes type deduction in template context.
r1-p008silent prediction offRedundant Parentheses Around Pack ExpansionRemoving parentheses around pack expansion breaks syntax, causing compile error.
r2-p001silent prediction offMacro Argument Substitutionmacros: the rewritten token comes from or spans a macro expansion, or a macro argument
r2-p002silentDependent Name Lookup FailureTaking away parentheses around a dependent name in a template, such as `(typename T::type)`, may hinder lookup and break instantiation.
r2-p003silent prediction offComma Expression Evaluation OrderRemoving parentheses around a comma-expression such as `(a, b)` changes evaluation order context, potentially altering which value is used in larger expressions.
r2-p004fix okInline Comment Loss on Parentheses LinesStripping parentheses that visually group code for readability may drop associated inline comments attached to the parentheses lines, reducing code clarity.
r2-p005silent prediction offTemporary Lifetime in Structured Bindingreferences vs values: lifetime of temporaries, dangling after a rewrite to auto or structured bindings
r2-p006invalidString Literal Type Deductionstring literal types, string_view vs std::string, char vs int in the rewritten code
r2-p007silent prediction offAssignment Expression in ConditionErasing parentheses around an assignment expression like `(x = y)` may prevent it from being treated as a single value in outer contexts, affecting use in conditions or function calls.
r2-p008fix okConstexpr Qualification Lossconst/volatile/noexcept/constexpr qualifiers dropped or added by the rewrite

Sources

r1-p001 · Redundant Parentheses Around Throw Expression
1#include <iostream>
2#include <exception>
3struct S { ~S() { std::cout << 'S'; } };
4int main() {
5 S s;
6 try { (throw std::runtime_error("err"), 0); }
7 catch (const std::exception& e) { std::cout << "Caught: " << e.what(); }
8}
Caught: errS
r1-p002 · Redundant Parentheses in For Loop Init
1#include <iostream>
2#include <vector>
3int main() {
4 std::vector<int> v{1,2,3};
5 auto it = v.begin();
6 for (; (it != v.end(), ++it, it != v.end()); ) {
7 std::cout << *it;
8 ++it;
9 }
10}
2
r1-p003 · Redundant Parentheses Around Overloaded Operator Call
1#include <iostream>
2struct X {
3 int val = 0;
4 operator int() { std::cout << "conv:"; return ++val; }
5};
6int main() {
7 X x;
8 int a = (x) + (x);
9 std::cout << "|" << a;
10}
--- orig.cpp	2026-10-17 16:08:04.999342785 -0400
+++ fixed.cpp	2026-10-17 16:08:07.850763565 -0400
@@ -5,6 +5,6 @@
 };
 int main() {
   X x;
-  int a = (x) + (x);
+  int a = x + x;
   std::cout << "|" << a;
 }
conv:conv:|3
r1-p004 · Redundant Parentheses Around Shift Expression
1#include <iostream>
2#include <limits>
3int main() {
4 unsigned long x = 1UL << 63;
5 unsigned long z = (x >> 1) + 1;
6 std::cout << z;
7}
4611686018427387905
r1-p005 · Redundant Parentheses Around Braced Init List
1#include <iostream>
2struct A { int x, y; A(int a, int b) : x(a), y(b) { std::cout << 'C'; } };
3int main() {
4 A a = (A){1, 2};
5 std::cout << a.x << a.y;
6}
C12
r1-p006 · Redundant Parentheses Around Sizeof Expression
1#include <iostream>
2int main() {
3 int x;
4 std::cout << sizeof(int)*sizeof(x);
5}
16
r1-p007 · Redundant Parentheses in Dependent Decltype Expression
1#include <iostream>
2template<typename T> auto foo(T t) -> decltype((t)) { return t; }
3int main() {
4 int x = 42;
5 auto&& r = foo(x);
6 std::cout << r;
7}
--- orig.cpp	2026-10-17 16:08:16.389891442 -0400
+++ fixed.cpp	2026-10-17 16:08:19.343531345 -0400
@@ -1,5 +1,5 @@
 #include <iostream>
-template<typename T> auto foo(T t) -> decltype((t)) { return t; }
+template<typename T> auto foo(T t) -> decltype(t) { return t; }
 int main() {
   int x = 42;
   auto&& r = foo(x);
42
r1-p008 · Redundant Parentheses Around Pack Expansion
1#include <iostream>
2template<typename... Args> void f(Args... args) {
3 (std::cout << ... << args);
4}
5int main() {
6 f(1, 2, 3);
7}
123
r2-p001 · Macro Argument Substitution
1#include <cstdio>
2#define VALUE (42)
3int main() {
4 int x = (VALUE);
5 printf("%d\n", x);
6 return 0;
7}
42
r2-p002 · Dependent Name Lookup Failure
1#include <cstdio>
2template<typename T> void foo() {
3 typename T::type x{}; // Parens around typename T::type would be redundant but removing breaks dependent lookup
4 (void)x;
5}
6struct S { using type = int; };
7int main() {
8 foo<S>();
9 printf("ok\n");
10 return 0;
11}
ok
r2-p003 · Comma Expression Evaluation Order
1#include <cstdio>
2int main() {
3 int a = 1, b = 2;
4 int x = (a, b);
5 printf("%d\n", x);
6 return 0;
7}
2
r2-p004 · Inline Comment Loss on Parentheses Lines
1#include <cstdio>
2int main() {
3 int x = (/* important initialization */ 42);
4 printf("%d\n", x);
5 return 0;
6}
--- orig.cpp	2026-10-17 16:08:31.464310816 -0400
+++ fixed.cpp	2026-10-17 16:08:31.938496183 -0400
@@ -1,6 +1,6 @@
 #include <cstdio>
 int main() {
-  int x = (/* important initialization */ 42);
+  int x = /* important initialization */ 42;
   printf("%d\n", x);
   return 0;
 }
42
r2-p005 · Temporary Lifetime in Structured Binding
1#include <cstdio>
2#include <utility>
3struct Temp { int v; Temp(int x) : v(x) {} ~Temp() { v = -1; } };
4Temp make_temp() { return Temp(99); }
5int main() {
6 auto [val] = (make_temp());
7 printf("%d\n", val);
8 return 0;
9}
99
r2-p006 · String Literal Type Deduction (generated program does not parse: orig.cpp:5:17: error: static assertion failed )
1#include <cstdio>
2#include <string_view>
3int main() {
4 auto s = ("hello");
5 static_assert(std::is_same_v<decltype(s), const char[6]>);
6 printf("%zu\n", sizeof(s));
7 return 0;
8}
r2-p007 · Assignment Expression in Condition
1#include <cstdio>
2int main() {
3 int a = 1, b = 2;
4 if ((a = b)) {
5 printf("%d\n", a);
6 }
7 return 0;
8}
2
r2-p008 · Constexpr Qualification Loss
1#include <cstdio>
2constexpr int get_five() { return 5; }
3int main() {
4 constexpr int x = (get_five());
5 printf("%d\n", x);
6 return 0;
7}
--- orig.cpp	2026-10-17 16:08:33.606229830 -0400
+++ fixed.cpp	2026-10-17 16:08:34.053846056 -0400
@@ -1,7 +1,7 @@
 #include <cstdio>
 constexpr int get_five() { return 5; }
 int main() {
-  constexpr int x = (get_five());
+  constexpr int x = get_five();
   printf("%d\n", x);
   return 0;
 }
5