SonarSource Rules
  • Products

    In-IDE

    Code Quality and Security in your IDE with SonarQube Ide

    IDE extension that lets you fix coding issues before they exist!

    Discover SonarQube for IDE

    SaaS

    Code Quality and Security in the cloud with SonarQube Cloud

    Setup is effortless and analysis is automatic for most languages

    Discover SonarQube Cloud

    Self-Hosted

    Code Quality and Security Self-Hosted with SonarQube Server

    Fast, accurate analysis; enterprise scalability

    Discover SonarQube Server
  • SecretsSecrets
  • ABAPABAP
  • AnsibleAnsible
  • ApexApex
  • AzureResourceManagerAzureResourceManager
  • CC
  • C#C#
  • C++C++
  • CloudFormationCloudFormation
  • COBOLCOBOL
  • CSSCSS
  • DartDart
  • DockerDocker
  • FlexFlex
  • GitHub ActionsGitHub Actions
  • GoGo
  • HTMLHTML
  • JavaJava
  • JavaScriptJavaScript
  • JSONJSON
  • JCLJCL
  • KotlinKotlin
  • KubernetesKubernetes
  • Objective CObjective C
  • PHPPHP
  • PL/IPL/I
  • PL/SQLPL/SQL
  • PythonPython
  • RPGRPG
  • RubyRuby
  • RustRust
  • ScalaScala
  • SwiftSwift
  • TerraformTerraform
  • TextText
  • TypeScriptTypeScript
  • T-SQLT-SQL
  • VB.NETVB.NET
  • VB6VB6
  • XMLXML
  • YAMLYAML
C

C static code analysis

Unique rules to find Bugs, Vulnerabilities, Security Hotspots, and Code Smells in your C code

  • All rules 315
  • Vulnerability13
  • Bug76
  • Security Hotspot19
  • Code Smell207

  • Quick Fix 19
Filtered: 34 rules found
pitfall
    Impact
      Clean code attribute
        1. "goto" should jump to labels declared later in the same function

           Code Smell
        2. Dynamic heap memory allocation should not be used

           Bug
        3. "setjmp" and "longjmp" should not be used

           Code Smell
        4. Macros should not be #define'd or #undef'd within a block

           Code Smell
        5. Object declarations should contain no more than 2 levels of pointer indirection

           Code Smell
        6. Functions without parameters should be declared with parameter type "void"

           Code Smell
        7. Recursion should not be used

           Code Smell
        8. Functions should not be defined with a variable number of arguments

           Code Smell
        9. Constants of unsigned type should have a "U" suffix

           Code Smell
        10. If a function has internal linkage then all re-declarations shall include the static storage class specifer

           Code Smell
        11. Literal suffix "L" for long integers shall be upper case

           Code Smell
        12. Macro arguments should not contain preprocessing directives

           Bug
        13. All the elements of an aggregate should be provided with an initial value

           Code Smell
        14. Macros should not be used as replacements for "typedef" and "using"

           Code Smell
        15. Keywords shall not be used as macros identifiers

           Code Smell
        16. Logical operators should not be confused with bitwise operators

           Code Smell
        17. Include directives should not rely on non-portable search strategy

           Code Smell
        18. "#include" paths should be portable

           Code Smell
        19. Array indices should be placed between brackets

           Code Smell
        20. Bit fields should not be used

           Code Smell
        21. Conditionally executed code should be reachable

           Bug
        22. Control characters should not be used in literals

           Code Smell
        23. Octal and hexadecimal escape sequences should be terminated

           Code Smell
        24. Preprocessor directives should not be indented

           Code Smell
        25. "goto" statements should not be used to jump into blocks

           Code Smell
        26. Related "if/else if" statements should not have the same condition

           Bug
        27. "static" should not be used for the size of an array parameter

           Code Smell
        28. "switch" statements should not be nested

           Code Smell
        29. The sign of an unsigned variable should not be tested

           Code Smell
        30. Octal values should not be used

           Code Smell
        31. "for" loop stop conditions should be invariant

           Code Smell
        32. Control structures should use curly braces

           Code Smell
        33. Variables should not be shadowed

           Code Smell
        34. Control should not be transferred into a complex logic block using a "goto" or a "switch" statement

           Code Smell

        All the elements of an aggregate should be provided with an initial value

        intentionality - clear
        maintainability
        Code Smell
        • pitfall

        When an array or an object of aggregate type is non-zero initialized, values for each element or field should be provided.

        Why is this an issue?

        How can I fix it?

        More Info

        In C or C++, it is possible to provide an initial value for the elements of an array. When fewer values are provided than the size of the array, the last elements of the array are zero-initialized for builtin-types (like int or pointers), and value-initialized otherwise. However, as soon as some values are provided, it is clearer to provide them all and not rely on these default initializations.

        int a1[5] = {1, 2, 3};              // Noncompliant, last two elements are initialized with 0
        int a2[4] = {1, 2, 3, 4, 5};        // Compliant
        int* a3[3] = {a1, a1 + 1};          // Noncompliant, the last pointer is null
        int* a4[3] = {a1, a1 + 1, nullptr}; // Compliant
        

        Similarly, when an aggregate class or struct is initialized, an initial value may be provided for each field. All remaining fields are initialized in the same manner as elements of an array, but this rule requests explicit initialization:

        struct Pod {
          int x;
          int y;
        };
        
        Pod p1{1};    // Noncompliant, `y` does not have an initial value
        Pod p2{1, 0}; // Compliant
        

        This behavior applies recursively when arrays and aggregates are nested:

        struct PodPair {
          Pod first;
          Pod second;
        };
        
        struct ArrayMember {
          int id;
          int vals[4];
        };
        
        int c1[2][2] = {{1}, {2}};  // Noncompliant, the second elements of each nested array do not have an initial value provided
        Pod c2[3] = {{1, 2}, {2}};  // Noncompliant, field `y` of `c2[1]` and whole `c2[2]` object do not have an initial value provided
        PodPair c3 = {{1}};         // Noncompliant, field `y` of `c3.first` and whole `c3.second` object do not have an initial value provided,
        ArrayMember c4 = {1, 2, 3}; // Noncompliant, the last two elements of `c4.vals` do not have an initial value provided
        

        This rule raises an issue when a non-zero initialization of an aggregate (array or class/struct), does not provide values for all its elements or fields.

        What is the potential impact?

        The intent of the code is unclear when the initializer omits the values for some of the elements or fields: Is the initial value skipped on purpose or is it an oversight? Is it because, after the initial code was written, the array size was changed, or a new field was added, and the initialization was not updated? In that case, the zero or default value may not be handled properly, leading to unexpected program behavior.

        As an illustration, if the field or element has a pointer type, it will be initialized with a null-pointer value, and may lead to null-pointer dereference.

        What about zero initialization?

        When initializing an array with a large number of elements, or a complex structure, it is often desired to set all the elements or fields to zero, or to their default values (for classes with default constructors). Such situations are usually indicated by an empty set of braces {} for C++, or braces with {0} or {NULL} in the case of C. The issue is not raised in such a situation.

        int a1[10] = {0}; // Compliant
        int a2[10] = {};  // Compliant
        Pod p1 = {0};     // Compliant
        PodPair c1 = {0}; // Compliant
        

        This exception also applies when the nested aggregate is zero-initialized:

        int c1[2][2]{{1, 2}, {}};     // Compliant
        Pod c2[3] = {{1, 2}, {}, {}}; // Compliant
        PodPair c3 = {{}, {1, 0}};    // Compliant
        ArrayMember c4{1, {}};        // Compliant
        

        What if designated initializers are used?

        The C standard provides a designated initialization syntax that explicitly denotes the field or element of the aggregate for which value is provided. This rule also raises an issue if the initial value for an element or field is not provided.

        int a1[3] = { [1] = 1, [2] = 2 };          // Noncompliant, first element do not have initial value provided
        int a2[3] = { [0] = 0, [1] = 1, [2] = 2 }; // Compliant
        Pod p1 = {.y = 10};                        // Noncompliant, `p.x` do not have initial value provided
        Pod p2 = {.x = 0, .y = 10};                // Compliant
        

        C++20 has adopted a limited version of this feature. This rule also raises an issue in the case of incomplete initializers.

        What if the field has a default member initializer?

        C++11 allows class fields to specify a default value that will be used if no other value is provided during construction. Such default member initializers cannot be used in aggregate types until C++14, which guarantees that the default value is used if the initializer list does not provide a value for the field. The issue is not raised when a field with a default value is not explicitly initialized, as an initial value was provided by the class author, and should be handled properly.

        struct Aggr {
          int a;
          int b;
          int c = 0;
        };
        
        Aggr a0{};           // Compliant, zero-initialization
        Aggr a1{10};         // Noncompliant, no initial value for field `b`, which does not have a default value
        Aggr a2{10, 20};     // Compliant, field `c` has a default value specified in `Aggr` definition
        Aggr a3{10, 20, 30}; // Compliant, all fields have initial values
        

        With the use of a designated initializer, such default value is meaningful for non-trailing fields:

        struct Mid {
          int a;
          int b = 10;
          int c;
        };
        
        Mid m1{.a = 10, .b = 10}; // Noncompliant, no initial value for field `c`, which does not have a default value
        Mid m1{.a = 10, .c = 2};  // Compliant, field `b` has a default value specified in `Mid` definition
        

        Can the issue be raised if I use parenthesis?

        C++20 allows aggregate types to be initialized using the parenthesis (()) in addition to the braces ({}), which simplifies writing generic code that creates an object (see S6872 for more details). This syntax also allows not to specify all values during initialization and this rule raises an issue in that case too.

        int a1[5](1, 2, 3);       // Noncompliant, the last two elements do not have an initial value
        int a2[4](1, 2, 3, 4, 5); // Compliant
        Pod p1(1);                // Noncompliant, `y` does not have an inital value
        Pod p2(1, 0);             // Compliant
        
          Available In:
        • SonarQube IdeCatch issues on the fly,
          in your IDE
        • SonarQube CloudDetect issues in your GitHub, Azure DevOps Services, Bitbucket Cloud, GitLab repositories
        • SonarQube ServerAnalyze code in your
          on-premise CI
          Developer Edition
          Available Since
          10.5

        © 2008-2025 SonarSource SA. All rights reserved.

        Privacy Policy | Cookie Policy | Terms of Use