Thanks to visit codestin.com
Credit goes to docs.codee.com

Skip to main content

C/C++ Basic Workflow

Goal

Walk you through the suggested basic workflow for using Codee, demonstrated with a C project.

Getting ready

For this demonstration, we will use a C implementation of a matrix multiplication. Start by cloning the repository:

git clone https://github.com/codee-com/codee-demos.git

Walkthrough of the workflow

Codee has multiple reports that can be useful, but in this basic workflow we will focus on the Codee checkers.

0. Compiler Invocation

Firstly navigate to the source code directory:

cd codee-demos/C/MATMUL

Before using Codee, ensure you have a working compiler invocation for the code to analyze. We will focus on the main.c file, which contains the core computational code. The file can be compiled as:

gcc main.c -c -I include/ -O3

To generate any Codee report, simply add the compiler invocation to the right of the codee invocation after a -- separator.

1. Checks Report

To apply the recommendations from the Open Catalog, the checks report identifies the precise locations in the source code where the improvement opportunities have been found. The default checks report pinpoints the file, line, and column for each opportunity:

Codee command
codee checks -- gcc main.c -c -I include/ -O3
Codee output
CHECKS REPORT

main.c:16:9 [PWR039] (level: L1): Consider loop interchange to improve the locality of reference and enable vectorization
main.c:9:9 [PWR053] (level: L1): Consider applying vectorization to forall loop
main.c:17:13 [PWR010] (level: L3): Avoid column-major array access in C/C++
main.c:18:17 [PWR048] (level: L3): Replace multiplication/addition combo with an explicit call to fused multiply-add
main.c:15:5 [PWR035] (level: L3): Avoid non-consecutive array access to improve performance
main.c:17:13 [RMK010] (level: L4): Strided memory accesses in the loop body may prevent vectorization

SUGGESTIONS

Use --check-id and --verbose to focus on specific subsets of checkers, e.g.:
codee checks --check-id PWR039 --verbose -- gcc main.c -c -I include/ -O3

1 target file, 2 functions, 6 loops, 55 LOCs successfully analyzed (6 checkers) and 0 non-analyzed files in 59 ms

Typically, you will also use the verbose mode of the checks report to generate detailed information on how to address each improvement opportunity:

Codee command
codee checks --verbose -- gcc main.c -c -I include/ -O3
Codee output
CHECKS REPORT

main.c:16:9 [PWR039] (level: L1): Consider loop interchange to improve the locality of reference and enable vectorization
Loops to interchange:
16: for (size_t j = 0; j < n; j++) {
17: for (size_t k = 0; k < p; k++) {
Suggestion: Interchange inner and outer loops in the loop nest to improve performance
Documentation:
https://open-catalog.codee.com/Checks/PWR039
AutoFix:
codee rewrite --check-id pwr039 --in-place main.c:16:9 -- gcc main.c -c -I include/ -O3

main.c:9:9 [PWR053] (level: L1): Consider applying vectorization to forall loop
Suggestion: Use 'rewrite' to automatically optimize the code
Documentation:
https://open-catalog.codee.com/Checks/PWR053
AutoFix (choose one option):
* Using OpenMP pragmas (recommended):
codee rewrite --check-id pwr053 --variant omp --in-place main.c:9:9 -- gcc main.c -c -I include/ -O3
* Using GNU pragmas:
codee rewrite --check-id pwr053 --variant gnu --in-place main.c:9:9 -- gcc main.c -c -I include/ -O3
* Using Intel pragmas:
codee rewrite --check-id pwr053 --variant intel --in-place main.c:9:9 -- gcc main.c -c -I include/ -O3
* Using LLVM compiler pragmas:
codee rewrite --check-id pwr053 --variant llvm --in-place main.c:9:9 -- gcc main.c -c -I include/ -O3
* Using combined pragmas, for example (for GNU and Intel pragmas):
codee rewrite --check-id pwr053 --variant gnu,intel --in-place main.c:9:9 -- gcc main.c -c -I include/ -O3

<...>

2. Autofix

In certain scenarios, Codee can automatically apply the suggested improvements to your code. The autofix feature is closely integrated with the verbose output of the checks report, as command-line invocations will be generated for all available autofixes.

Codee command
codee rewrite --check-id pwr039 --in-place main.c:16:9 -- gcc main.c -c -I include/ -O3
Codee output
Results for file 'main.c':
Successfully applied AutoFix to the loop at 'main.c:16:9' [using loop interchange]:
[INFO] Loops interchanged:
- main.c:16:9
- main.c:17:13

Successfully main.c

Codee automatically marks the rewritten code with comments, allowing you to double-check the changes to ensure correctness:

git diff main.c
diff --git a/C/MATMUL/main.c b/C/MATMUL/main.c
index ecc66be..fec86a8 100644
--- a/C/MATMUL/main.c
+++ b/C/MATMUL/main.c
@@ -13,8 +13,10 @@ void matmul(size_t m, size_t n, size_t p, double **A, double **B, double **C) {

// Accumulation
for (size_t i = 0; i < m; i++) {
- for (size_t j = 0; j < n; j++) {
- for (size_t k = 0; k < p; k++) {
+ // Codee: Loop modified by Codee (2025-11-06 10:46:05)
+ // Codee: Technique applied: loop interchange
+ for (size_t k = 0; k < p; k++) {
+ for (size_t j = 0; j < n; j++) {
C[i][j] += A[i][k] * B[k][j];
}
}

3. Compilation Database

Codee requires the compiler invocation for each file to analyze. Sometimes the compiler invocation can be a huge command and there can be also multi-file projects. The recommended approach for this is to use a compilation database to efficiently handle the compiler invocations for different source files. To see further details on how to generate the compile_commands.json file refer to the following guide: Compilation Database Generation.