When I first started programming in C, I was full of hope to quickly master this powerful programming language, imagining that I could write efficient code like those programming experts. However, reality hit me hard; every time I confidently pressed the compile and run button, eagerly anticipating a perfectly running program, I was instead met with various error messages that left me feeling defeated. Those dense error codes were like a swarm of little monsters, mercilessly declaring the “death” of my program. I believe many beginners in C have had similar experiences, often staring blankly at these errors, completely unsure of where to start troubleshooting. Sometimes, a tiny syntax error can cost us hours or even days of debugging. It feels like groping in the dark, unable to find a glimmer of light.
However, C language error codes are not an incomprehensible “heavenly book” without rules. Behind each error code lies a specific problem that occurred during program execution. As long as we can understand the meaning of these error codes, we can possess a “universal key” that easily opens the door to problem-solving. Today, I will share a comprehensive guide to common C language error codes, hoping to help everyone take fewer detours on the programming path and make compilation and runtime errors no longer a source of frustration.
1. Common Compilation Error Codes and Their Meanings
1.1 Syntax Error Types
(1) Missing Semicolon: The error code “error: expected ‘;’ before ‘}’ token” indicates that a semicolon is missing before the “}” symbol. This is because every statement in C must end with a semicolon. For example, the code “int main (){int a=5 printf (“% d”,a)}” triggers this error because there is no semicolon after “int a=5”.
#include <stdio.h>
int main() {
int a = 10
printf("%d", a);
return 0;
}
Correction method: Add a semicolon at the end of the statement int a = 10, i.e., int a = 10;.
(2) Mismatched Parentheses: The error code “error: expected ‘)’ before ‘identifier'” or “error: expected ‘}’ before ‘identifier'” indicates that parentheses (either ( and ) or { and }) are not correctly paired. For example, the code “int main (){if (a>0 {printf (“ok”);})}” triggers this error because the “(” after if is not closed with a corresponding “)”.
#include <stdio.h>
int main() {
if (1 > 0 {
printf("Hello, World!\n");
}
return 0;
}
Correction method: Add a closing parenthesis after if (1 > 0, i.e., if (1 > 0).
(3) Spelling Error: The error code “error: ‘xxxx’ undeclared (first use in this function)” indicates that an undeclared identifier (which could be a variable, function, etc.) is used, possibly due to a spelling mistake. For example, in the code “int main (){prinft (“Hello”); return 0;}” the misspelling of “printf” as “prinft” triggers this error.
#include <stdio.h>
int main() {
int numbe = 10; // Should be number
printf("%d", numbe);
return 0;
}
Correction method: Change numbe to the correct number.
(4) Missing Header File:
The error code “fatal error: xxx.h: No such file or directory” indicates that the program uses a function or type from a header file that has not been included, or the header file path is incorrect. For example, the code “int main (){printf (“Hello”); return 0;}” triggers this error because “stdio.h” is not included.
int main() {
printf("Hello, World!");
return 0;
}
Correction method: Add #include <stdio.h> at the beginning of the file.
★These types of errors stem from code not conforming to C language syntax rules, which the compiler can detect during the parsing phase. Syntax logic must be corrected before recompiling.
| Error Code | Chinese Equivalent | Core Analysis |
| fatal error C1003 | (Compilation Error) Too many errors, compilation stopped | The number of errors exceeds the compiler’s limit; previously detected errors must be corrected before recompiling |
| fatal error C1004 | (Compilation Error) File not ended | Function/structure missing “}”, mismatched parentheses, or incomplete comment symbol “/…/” |
| fatal error C1903 | (Compilation Error) Cannot recover from previous errors, compilation stopped | Earlier errors caused code structure confusion; prioritize fixing earlier errors |
| error C2001 | (Compilation Error) New line in constant | String constants not connected with “\” or double quotes written across multiple lines |
| error C2006 | (Compilation Error) #include command needs a filename | Header file not enclosed in double quotes or angle brackets, e.g., “#include stdio.h” |
| error C2007 | (Compilation Error) #define syntax error | “#define” missing macro name, e.g., only writing “#define” |
| error C2008 | (Compilation Error) Unexpected xxx in macro definition | No space between macro name and replacement string, e.g., “#define TRUE”1″” |
| error C2009 | (Compilation Error) Formal parameter of macro with arguments reused | Formal parameters of macro have the same name, e.g., “#define s (a,a) (a*a)” |
| error C2010 | (Compilation Error) Unknown character in formal parameter list of macro with arguments | Parameter list contains irrelevant characters, e.g., “#define s (r” |
| error C2014 | (Compilation Error) Only spaces allowed before preprocessor commands | Non-space characters before preprocessor commands (e.g., #include) or not on a separate line |
| error C2015 | (Compilation Error) Constant contains multiple characters | Character constant contains multiple characters within single quotes, e.g., “char error = ‘error’;” |
| error C2017 | (Compilation Error) Illegal escape character | Escape character outside of single quotes or double quotes, e.g., “char error = ‘ ‘\n;” |
| error C2018 | (Compilation Error) Unknown character 0xhh | Code contains Chinese punctuation, e.g., “char error = ‘E’;” (semicolon is Chinese) |
| error C2019 | (Compilation Error) Expected preprocessor command, but invalid character present | Invalid character after preprocessor command #, e.g., “#!define TRUE 1” |
| error C2021 | (Compilation Error) Expected exponent value, cannot be a character | Floating-point scientific notation missing exponent, e.g., “123.456E” |
| error C2039 | (Compilation Error) Identifier 1 is not a member of identifier 2 | Incorrectly referencing a member of a structure/union/class, e.g., accessing a non-existent structure member |
| error C2041 | (Compilation Error) Invalid number for n base | Octal contains 8/9, hexadecimal contains non 0-9/A-F, e.g., “int i = 081;” |
| error C2048 | (Compilation Error) More than one default statement | Multiple defaults in a switch statement, need to delete the extra ones |
| error C2050 | (Compilation Error) Switch expression is not an integer | Switch expression is not int/char or other integer types, e.g., “switch (“a”)” |
| error C2051 | (Compilation Error) Case expression is not a constant | Non-constant expression after case, e.g., “case a:” (a is a variable) |
| error C2052 | (Compilation Error) Case expression type is illegal | Case expression is not an integer constant, does not match switch expression type |
| error C2057 | (Compilation Error) Expected constant expression | Array length uses a variable (C89 standard), e.g., “int n=10; int a [n];” |
| error C2058 | (Compilation Error) Constant expression is not an integer | Array length is not an integer constant, e.g., “int a [3.5];” |
| error C2059 | (Compilation Error) Syntax error ‘xxx’ | Missing/multiple symbols (e.g., parentheses, semicolons), or code structure does not conform to syntax |
| error C2064 | (Compilation Error) Cannot recognize function language | 1. Function parameters/expressions are incorrect (e.g., “sqrt (s (s-a)(s-b)(s-c));”); 2. Variable and function have the same name (e.g., “j=i ();” where i is a variable) |
| error C2065 | (Compilation Error) Undefined identifier xxx | 1. Missing header file (e.g., using printf without #include <stdio.h>); 2. Variable/function not declared, or spelling/case error |
| error C2078 | (Compilation Error) Too many initial values | Number of array initialization values exceeds length, e.g., “int b [2]={1,2,3};” |
| error C2082 | (Compilation Error) Redefinition of formal parameter xxx | Redefining formal parameters in the function body, e.g., “void fun (int x){int x;}” |
| error C2084 | (Compilation Error) Function xxx already defined | Function redefined; VC++6.0+ supports overloading, but parameters must differ |
| error C2086 | (Compilation Error) Identifier xxx redefined | Variable/array/macro, etc., have the same name, e.g., “int a=5; int a=10;” |
| error C2087 | (Compilation Error) Unknown subscript | Two-dimensional array missing second dimension length, e.g., “int a [3][];” |
| error C2100 | (Compilation Error) Illegal indirect access operator “*” | Non-pointer variable used with “*”, e.g., “int a=5; int b=*a;” |
| error C2105 | (Compilation Error) Operator requires lvalue | Non-lvalue used with ++/– and other operators, e.g., “(a+b)++;” |
| error C2106 | (Compilation Error) Left operand of operator must be lvalue | Assignment operator left is an expression, e.g., “a+b=1;” |
| error C2110 | (Compilation Error) Two pointer variables cannot be added | Pointer variables added directly (meaningless), e.g., “a = pa + pb;” |
| error C2117 | (Compilation Error) Array xxx boundary overflow | Character array initialization string length exceeds array (including ‘\0’), e.g., “char str [4] = “abcd”;” |
| error C2118 | (Compilation Error) Subscript is negative or too large | Array subscript is negative or exceeds array length (e.g., int a [5]; a [10]=3;) |
| error C2124 | (Compilation Error) Division by zero or modulo by 0 | Divisor is 0, e.g., “int i = 1 / 0;” |
| error C2133 | (Compilation Error) Array xxx length unknown | Array not initialized and length not specified, e.g., “int a [];” |
| error C2137 | (Compilation Error) Character constant is empty | Single quotes contain no characters, e.g., “char c = ”;” |
| error C2143 | (Compilation Error) Missing language symbol 1 before identifier or language symbol 2 | Missing “{“, “)” or “;” etc., e.g., “if (a>0) printf (“ok”)” (missing semicolon) |
| error C2144 | (Compilation Error) Missing ‘)’ before xxx type | Function call requires actual parameter type, e.g., “fun (int 5);” |
| error C2146 | (Compilation Error) Missing language symbol 1 before identifier | Same as C2143, missing key symbol causes syntax error |
| error C2181 | (Compilation Error) Illegal else without matching if | Extra “;” after if (no matching else), or compound statement missing “{}” |
| error C2196 | (Compilation Error) Case value 0 already used | Duplicate case values in switch, e.g., two “case 0:” |
| error C2447 | (Compilation Error) Missing function header (is it an old-style parameter list?) | Extra “;” after function header “()”, or using old-style C parameter list (e.g., “void fun (a) int a; {}”) |
| error C2448 | (Compilation Error) : function-style initializer appears to be a function definition | Function definition format error, e.g., function initializer misidentified as function definition |
| error C2450 | (Compilation Error) Switch expression is of illegal xxx type | Switch expression is not int/char, e.g., “switch (3.14)” |
| error C2466 | (Compilation Error) Cannot allocate array of length 0 | Array length is 0, e.g., “int a [0];” |
| error C2601 | (Compilation Error) Function xxx definition illegal | Defining a function within a function (nested definition, not supported in C) |
| error C2632 | (Compilation Error) Type 1 immediately followed by type 2, which is illegal | Writing multiple types consecutively, e.g., “int float i;” |
| warning C4003 | (Compilation Warning) Macro xxx has insufficient actual parameters | Missing parameters when calling a macro with parameters, e.g., “#define ADD (a,b) a+b; ADD (5);” |
| warning C4067 | (Compilation Warning) Unexpected symbol after preprocessor command – expecting new line | Extra characters after preprocessor command, e.g., “#include<iostream.h>;” (extra semicolon) |
| warning C4091 | (Compilation Warning) Ignore type specification when no variable is declared | Only type written without variable, e.g., “int ;” (does not affect execution, can be deleted) |
| warning C4101 | (Compilation Warning) Variable xxx defined but not used | Variable declared but not referenced, can delete that variable definition |
| warning C4390 | (Compilation Warning) ‘;’ control statement is an empty statement, is this the program’s intention? | Extra “;” after if/loop (body is empty), e.g., “if (a>0); {printf (“ok”);}” |
| warning C4508 | (Compilation Warning) Function xxx should have a return value, assuming return type is void | Function return type not declared (defaults to int), e.g., “main (){}” (recommended to write “void main ()”) |
| warning C4552 | (Compilation Warning) Operator has no effect; expecting side-effect operator | Operation without side effects (e.g., “i+j;”), operation result not used |
| warning C4553 | (Compilation Warning) “==” operator invalid; is it “=”? | Accidentally writing assignment “=” as equality “==” without assignment, e.g., “i==j;” |
| warning C4700 | (Compilation Warning) Variable xxx used before initialization | Variable used directly without assignment (e.g., “int a; printf (“% d”,a);”); if using scanf may miss “&” |
| warning C4715 | (Compilation Warning) Function xxx does not have a return value for all control paths | Some branches of the function have no return (e.g., “int fun (int a){if (a>0) return 1;}”; no return when a<=0) |
| warning C4723 | (Compilation Warning) Possible division by 0 | Divisor may be 0 (e.g., “int a=0; int b=5/a;”); need to add checks to avoid |
| warning C4804 | (Compilation Warning) ‘<‘: unsafe use of boolean type | Boolean type involved in comparison (e.g., “0<=x<10”, in C first calculates 0<=x, result (0/1) then compares with 10, logical error) |
1.2 Type Error Types
(1) Assignment Type Mismatch: The error code “error: assignment to ‘xxx’ from ‘yyy’ makes pointer from integer without a cast” indicates that an incompatible data type is assigned to a variable. For example, in the code “int *p; p = 10;” assigning the integer 10 to the pointer variable p triggers this error.
#include <stdio.h>
int main() {
int num = "10"; // String cannot be directly assigned to integer
return 0;
}
Correction method: If you want to convert a string representation of a number to an integer, you can use the atoi function, e.g., int num = atoi(“10”);.
(2) Function Return Type Mismatch: The error code “error: return type conflicts with previous declaration” indicates that the actual return type of the function does not match the declared return type. For example, in the code “int func (); void func (){return;}” the function is declared as int type but actually returns void, triggering this error.
#include <stdio.h>
int add(int a, int b);
int main() {
int result = add(3, 5);
printf("%d", result);
return 0;
}
float add(int a, int b) { // Declared as int type return, actually float
return a + b;
}
Correction method: Change the return type of the function definition to int, i.e., int add(int a, int b).
(3) Function Parameter Type Mismatch: The error codes “error: too many arguments to function ‘xxx'”, “error: too few arguments to function ‘xxx'” and “error: argument ‘x’ of ‘xxx’ has an invalid type” indicate that the number or type of parameters passed when calling the function does not match the function definition. For example, in the code “int add (int a, int b){return a+b;} int main (){add (1); add (2,3,4); add (“5″,6); return 0;}” these errors are triggered due to too few, too many, or incorrect types of parameters.
#include <stdio.h>
int add(int a, int b);
int main() {
int result = add(3); // Missing one parameter
printf("%d", result);
return 0;
}
int add(int a, int b) {
return a + b;
}
Correction method: Pass the correct number and type of parameters according to the function definition, i.e., int result = add(3, 5);.
★These types of errors are caused by data type mismatches or improper type usage, and it is necessary to ensure that the types of variables, function parameters/return values are consistent.
| Error Code | Chinese Equivalent | Core Analysis |
| error C2296 | (Compilation Error) Left (right) operand type of % operation is float, which is illegal | Modulo “%” operand is not int, e.g., “float a=5.0; int b=a%2;”; need to force conversion (e.g., “(int) a%2”) |
| error C2297 | (Compilation Error) Left (right) operand type of % operation is float, which is illegal | Same as C2296, % only supports int type operands |
| error C2371 | (Compilation Error) Identifier xxx redefined; base types differ | Same identifier defined as different types, e.g., “int a; float a;” |
| error C2440 | (Compilation Error) Assignment operation, cannot convert from character array to character | Character variable assigned a string, e.g., “char c = “a”;” (should write “char c = ‘a’;” or “char c [] = “a”;”) |
| error C2660 | (Compilation Error) Function xxx cannot take n parameters | Number of actual parameters does not match formal parameters, e.g., “sin (x,y);” (sin only needs 1 parameter) |
| error C2664 | (Compilation Error) Function xxx cannot convert nth parameter from type 1 to type 2 | Actual parameter type does not match formal parameter, e.g., “void fun (int a); fun (3.14);” (need to force conversion “fun ((int) 3.14)”) |
| error C2676 | (Compilation Error) binary ‘<<‘/’>>’ : class does not define this operator | Stream operator used incorrectly (e.g., “cin<<x; cout>>y;”), correct is “cin>>x; cout<<y;” |
| error C4244 | (Compilation Warning) Assignment operation, converting from data type 1 to data type 2, may lose data | High precision to low precision (e.g., float→int loses decimal, double→float loses precision), e.g., “int a=3.14;” |
| error C4305 | (Compilation Warning) Initialization, truncating double constant to float type | Float variable assigned double constant (e.g., “float a=3.1415926535;”), precision loss (does not affect most scenarios) |
| error C4716 | (Compilation Error) Function xxx must return a value | Non-void function has no return value, e.g., “int fun (){printf (“ok”);}” (need to add “return 0;”) |
1.3 Link Error Types
(1) Function Undefined: The error code “undefined reference to ‘xxx'” indicates that a function that has not been defined is called. For example, in the code “void func (); int main (){func (); return 0;}” only declares the function func but does not define its implementation, triggering this error.
#include <stdio.h>
void fun();
int main() {
fun();
return 0;
}
Correction method: Add the definition of the function fun, for example:
#include <stdio.h>
void fun() {
printf("This is fun function.\n");
}
int main() {
fun();
return 0;
}
(2) Redefinition: The error code “multiple definition of ‘xxx'” or “error: redefinition of ‘xxx'” indicates that the same function or global variable has been defined multiple times in the same scope. For example, in the code “int a=1; int a=2; void func (){} void func (){}” the variable a and function func are redefined, triggering this error.
// file1.c
int num = 10;
// file2.c
int num = 20;
Correction method: Keep only one definition, or change one of the definitions to a declaration (add extern before the variable or function).
(3) Library File Link Issues: The error code “undefined reference to ‘function_in_library'” indicates that the program uses a function from a library but has not correctly linked that library. For example, in the code “#include <math.h> int main (){sqrt (4); return 0;}” using the math library function sqrt without linking the math library triggers this error.
#include <stdio.h>
#include <math.h>
int main() {
double result = sqrt(4.0);
printf("%lf", result);
return 0;
}
Compilation may report errors (different compilers may have slightly different error messages).
Correction method: Add the library link option during compilation, for example, when using gcc, add -lm, i.e., gcc -o test test.c -lm.
★These types of errors occur during the linking phase after compilation passes, often due to undefined functions, redefinitions, or executable files being occupied.
| Error Code | Chinese Equivalent | Core Analysis |
| fatal error LNK1104 | (Link Error) Cannot open file Debug/Cpp1.exe | Executable file path is incorrect or corrupted, need to recompile and link |
| fatal error LNK1168 | (Link Error) Cannot open Debug/Cpp1.exe file to rewrite content | Executable file is running (not closed), need to close it and recompile |
| fatal error LNK1169 | (Link Error) One or more multiple defined symbols occurred | Symbols (e.g., functions, global variables) are redefined, often appearing simultaneously with LNK2005 |
| error LNK2001 | (Link Error) Unresolved external identifier main | Spelling error in main function (e.g., “void mian ()”), or main not defined |
| error LNK2005 | (Link Error) Main function already defined in Cpp1.obj file | Multiple source files define main, or previous workspace not closed (residual main) |
2. Other Common Error Codes
2.1 Memory-Related Errors
(1) Memory Overflow: Runtime errors such as “Segmentation fault (core dumped)” usually occur when the program tries to access data beyond the allocated memory range. For example, in the code “int a [2]; a [5] = 10;” accessing the array out of bounds triggers this error.
#include <stdio.h>
int main() {
int arr[5];
for (int i = 0; i <= 5; i++) { // Out of bounds access, i=5 exceeds array range
arr[i] = i;
}
return 0;
}
Prevention method: Carefully check array subscripts and the size of dynamic memory allocation to ensure no out-of-bounds access.
(2) Null Pointer Reference: Runtime errors such as “Segmentation fault (core dumped)” occur when dereferencing a null pointer, which means trying to access memory pointed to by a pointer with a value of NULL. For example, in the code “int *p = NULL; *p = 5;” dereferencing the null pointer p triggers this error.
#include <stdio.h>
int main() {
int *p = NULL;
*p = 10; // Dereferencing null pointer
return 0;
}
Prevention method: Before using a pointer, check if the pointer is NULL, for example:
#include <stdio.h>
int main() {
int *p = NULL;
if (p!= NULL) {
*p = 10;
}
return 0;
}
(3) Accessing Freed Memory: Runtime errors such as “Segmentation fault (core dumped)” and other undefined behavior errors may occur when accessing memory that has been freed. For example, in the code “int *p = malloc (4); free (p); *p = 5;” dereferencing p after freeing the memory it points to triggers this error.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p = (int *)malloc(sizeof(int));
*p = 10;
free(p);
*p = 20; // Accessing freed memory
return 0;
}
Prevention method: After freeing memory, set the pointer to NULL, so that if accessed again, it can be checked through NULL to avoid errors, i.e., free(p); p = NULL;.
★ These types of errors are related to memory allocation and access, which may cause the program to crash. It is necessary to pay attention to array boundaries and pointer usage specifications.
| Error Code | Chinese Equivalent | Core Analysis |
| error C2117 | (Compilation Error) Array xxx boundary overflow | Character array initialization string length exceeds array (including ‘\0’), e.g., “char str [4] = “abcd”;” (str needs length 5) |
| error C2118 | (Compilation Error) Subscript is negative or too large | Array subscript out of bounds (negative subscript or exceeds array length), e.g., “int a [5]; a [10] = 1;” |
| error C2124 | (Compilation Error) Division by zero or modulo by 0 | Divisor is 0 (memory access has no direct correlation, but may cause calculation errors) |
2.2 File Operation Errors
(1) File Not Found: The “fopen: No such file or directory” message output by perror (may vary slightly between systems) indicates that the specified file does not exist when using the fopen function to open a file. For example, in the code “FILE *f = fopen (“nonexistent.txt”, “r”); if (!f) perror (“fopen”);” trying to open the non-existent “nonexistent.txt” file triggers this error.
#include <stdio.h>
int main() {
FILE *fp = fopen("nonexistent.txt", "r");
if (fp == NULL) {
perror("fopen");
return 1;
}
fclose(fp);
return 0;
}
Response strategy: Check if the file name and path are correct, ensuring the file actually exists.
(2) Too Many Files Open: In Linux systems, the “Too many open files” message output by perror indicates that the number of files the program tries to open simultaneously exceeds the maximum number of file descriptors allowed by the system. For example, if fopen is called in a loop to open a large number of files without closing them, this error will be triggered.
#include <stdio.h>
int main() {
FILE *fp[1000];
for (int i = 0; i < 1000; i++) {
fp[i] = fopen("test.txt", "r");
if (fp[i] == NULL) {
perror("fopen");
return 1;
}
}
// File closing operation omitted here
return 0;
}
Response strategy: Manage file opening and closing operations reasonably, timely closing files that are no longer in use, or increase the maximum number of file descriptors allowed by the system (requires administrator privileges).
(3) Invalid File Name: The “fopen: Invalid argument” message output by perror indicates that the file name passed to the fopen function does not conform to the system’s specified format or contains illegal characters. For example, in the code “FILE *f = fopen (“test:file.txt”, “r”); if (!f) perror (“fopen”);” the file name contains the illegal character “:” triggers this error.
#include <stdio.h>
int main() {
FILE *fp = fopen("test:file.txt", "r"); // File name contains colon, may be illegal in some systems
if (fp == NULL) {
perror("fopen");
return 1;
}
fclose(fp);
return 0;
}
Response strategy: Ensure that the file name conforms to the operating system’s naming rules and does not contain illegal characters.
(4) Macro Definition Syntax Error: The error code “error: expected identifier or ‘(‘ before numeric constant” indicates that the macro definition syntax is incorrect (e.g., missing macro name, parameter format error, etc.). For example, in the code “#define 5 VALUE; int a = VALUE;” the macro definition is missing a macro name, triggering this error.
#include <stdio.h>
#define 10 // Missing macro name
int main() {
return 0;
}
Solution suggestion: Check the syntax of the macro definition to ensure that the macro name is correctly defined, and that the macro parameters and replacement parts are written correctly. For example, a correct macro definition could be #define MAX 10.
(5) Preprocessor Command Usage Error: The error codes “error: #if without #endif” or “error: #ifdef without #endif” etc., indicate that preprocessor conditional commands (such as #if, #ifdef) do not have a correctly matching ending command #endif. For example, in the code “#ifdef DEBUG printf (“Debug”);” the lack of #endif triggers this error.
#include <stdio.h>
#ifdef DEBUG
printf("This is debug information.\n");
// Missing #endif
int main() {
return 0;
}
Solution suggestion: Carefully check the pairing of preprocessor commands to ensure that each #if, #ifdef, etc., has a corresponding #endif.
3. How to Quickly Locate and Resolve Errors
3.1 Utilizing Compiler Error Messages
When we compile C language programs, the compiler provides detailed error messages. These messages usually indicate the file name and line number where the error occurred, as well as the general type of error. For example, common syntax error messages might look like error: expected ‘;’ before ‘return’, which clearly tells us that a semicolon is missing before the return statement, and we can quickly locate the line in the code where the error occurred using the line number. In command-line compilation, error messages are directly output to the terminal; if using an integrated development environment (IDE) like Visual Studio Code, Dev-C++, etc., error messages are displayed in a dedicated error message area, and generally, you can directly click on the error message to jump to the corresponding line of code, which is very convenient.
#include <stdio.h>
// This is a C language program example containing various common errors
int main() {
int x = 10
int y = 20;
// Missing semicolon
printf("x = %d", x)
// Undeclared variable
z = x + y;
// Function not declared
result = add(x, y);
// Mismatched parentheses
if (x > y {
printf("x 大于 y\n");
}
// Incorrect comment end symbol
/* This is a comment
printf("This line will not be executed\n");
// Array out of bounds
int arr[5] = {1, 2, 3, 4, 5};
printf("Array sixth element: %d\n", arr[5]);
// Type mismatch
char c = 1234;
// Function return value issue
return
// Incorrect format specifier
printf("x 的值是 %s\n", x);
}
// Function definition
int add(int a, int b) {
return a + b
}
When using GCC to compile, you will receive error messages similar to the following:
error.c: In function ‘main’:
error.c:7:13: error: expected ‘;’ before ‘int’
7 | int x = 10
| ^
| ;
8 | int y = 20;
| ~~~
error.c:11:24: error: expected ‘;’ before ‘return’
11 | printf("x = %d", x)
| ^
| ;
error.c:14:5: error: ‘z’ undeclared (first use in this function)
14 | z = x + y;
| ^
error.c:17:10: error: ‘result’ undeclared (first use in this function)
17 | result = add(x, y);
| ^
error.c:17:17: warning: implicit declaration of function ‘add’ [-Wimplicit-function-declaration]
17 | result = add(x, y);
| ^~~
error.c:20:13: error: expected ‘)’ before ‘{’ token
20 | if (x > y {
| ^
| )
| ?
21 | printf("x 大于 y\n");
| ~~~~~~
error.c:31:12: warning: overflow in conversion from ‘int’ to ‘char’ changes value from ‘1234’ to ‘-46’ [-Woverflow]
31 | char c = 1234;
| ^
error.c:34:12: error: expected expression before ‘return’
34 | return
| ^
error.c:37:32: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
37 | printf("x 的值是 %s\n", x);
| ^
| |
| int
| %d
error.c: At top level:
error.c:43:1: error: expected ‘;’ before ‘}’ token
43 | }
| ^
error.c:39:5: note: to match this ‘{’
39 | int add(int a, int b) {
| ^
error.c:42:16: error: expected ‘;’ before ‘}’ token
42 | return a + b
| ^
| ;
43 | }
| ~
Corrected code:
#include <stdio.h>
// Function declaration
int add(int a, int b);
int main() {
int x = 10;
int y = 20;
printf("x = %d\n", x);
int z = x + y;
int result = add(x, y);
if (x > y) {
printf("x 大于 y\n");
}
/* This is a comment */
printf("This line will be executed\n");
int arr[5] = {1, 2, 3, 4, 5};
printf("Array fifth element: %d\n", arr[4]);
char c = 'A';
printf("x 的值是 %d\n", x);
return 0;
}
// Function definition
int add(int a, int b) {
return a + b;
}
Error messages usually indicate the type of error (error or warning), display the file name and line number where the error occurred, provide a specific description of the error, and offer suggestions for fixing it. In an IDE, directly clicking on the error message can jump to the corresponding line of code, greatly improving debugging efficiency.
3.2 Analyzing with Error Code Definitions
Simply looking at the compiler’s surface prompts may not be enough; at this point, combining the previously mentioned error code definitions becomes crucial. For example, encountering the error “undefined reference to ‘xxx'” indicates a function undefined issue. This requires checking whether the function definition exists, or whether it is in the correct file, and whether the parameter and return types of the function declaration and definition are consistent. Similarly, for the error “multiple definition of ‘xxx'”, knowing it is a redefinition issue allows us to check whether the same variable or function is defined multiple times in the code. By understanding the essence of errors through error code definitions, we can more accurately resolve issues.
#include <stdio.h>
// Example 1: undefined reference to 'add'
// Error reason: Function declaration and definition do not match
// Function declaration
int add(int a, int b); // Declared as returning int type
// Function definition - Error: Return type mismatch
void add(int a, int b) {
return a + b; // This will cause a conflict
}
// Example 2: multiple definition of 'global_var'
// Error reason: Global variable redefined
int global_var = 10; // First definition
// Example 3: conflicting types for 'multiply'
// Error reason: Function type conflict
// Implicitly declared as int multiply(...)
int result = multiply(5, 3);
// Actually defined as double type
double multiply(int a, int b) {
return (double)a * b;
}
// Example 4: redefinition of 'MAX_SIZE'
// Error reason: Macro redefined
#define MAX_SIZE 100
#define MAX_SIZE 200 // Redefinition
// Example 5: expected declaration specifiers or '...' before 'value'
// Error reason: Missing function parameter type
void print_value(value) { // Missing parameter type
printf("Value: %d\n", value);
}
int main() {
int x = 5, y = 3;
// Call function
int sum = add(x, y);
printf("Sum: %d\n", sum);
// Use global variable
printf("Global var: %d\n", global_var);
// Redefine global variable - redefinition
int global_var = 20;
// Call multiply function
printf("Multiply result: %.2f\n", multiply(x, y));
// Use macro
int array[MAX_SIZE];
// Call print_value function
print_value(100);
return 0;
}
(1) “undefined reference to ‘add’” The error reason is that the function declaration and definition do not match. The solution is to check and ensure that the declaration and definition of the add function are completely consistent in function name, parameter types and counts, and return type.
// Correct function declaration and definition
int add(int a, int b); // Declaration
int add(int a, int b) { // Definition - Return type consistent
return a + b;
}
(2) “multiple definition of ‘global_var’” The error reason is that the global variable is redefined. The solution is to check whether the same global variable is defined in multiple places in the code, keeping only one definition.
int global_var = 10; // Only define once
int main() {
// Use or modify within the function, rather than redefining
global_var = 20; // Correct
printf("Global var: %d\n", global_var);
return 0;
}
(3) “conflicting types for ‘multiply’” The error reason is that there is a function type conflict. The solution is to check the declaration and definition of the multiply function to ensure that its return type and parameter types are completely consistent.
// Declare function first
double multiply(int a, int b);
int main() {
// Then call
double result = multiply(5, 3);
return 0;
}
// Finally define
double multiply(int a, int b) {
return (double)a * b;
}
(4) “redefinition of ‘MAX_SIZE’” The error reason is that the macro is redefined. The solution is to check whether MAX_SIZE macro is defined multiple times in the code, deleting the duplicate definition and keeping only one.
// Define only once
#define MAX_SIZE 100
// Or use conditional compilation
#ifndef MAX_SIZE
#define MAX_SIZE 100
#endif
(5) “expected declaration specifiers or ‘…’ before ‘value’” The error reason is that the function parameter type is missing. The solution is to specify the correct data type for the function parameter “value”, such as changing “void func (value)” to “void func (int value)”.
// Correctly declare parameter type
void print_value(int value) {
printf("Value: %d\n", value);
}
Corrected complete code
#include <stdio.h>
// Function declaration
int add(int a, int b);
double multiply(int a, int b);
void print_value(int value);
// Macro definition - only define once
#ifndef MAX_SIZE
#define MAX_SIZE 100
#endif
// Global variable - only define once
int global_var = 10;
int main() {
int x = 5, y = 3;
// Call add function
int sum = add(x, y);
printf("Sum: %d\n", sum);
// Modify global variable
global_var = 20;
printf("Global var: %d\n", global_var);
// Call multiply function
double result = multiply(x, y);
printf("Multiply result: %.2f\n", result);
// Use macro
int array[MAX_SIZE];
printf("Array size: %d\n", MAX_SIZE);
// Call print_value function
print_value(100);
return 0;
}
// Function definition
int add(int a, int b) {
return a + b;
}
double multiply(int a, int b) {
return (double)a * b;
}
void print_value(int value) {
printf("Value: %d\n", value);
}
Common error types and solution ideas are as follows: In link errors, “undefined reference to ‘xxx'” requires checking whether the function/variable is defined and whether the declaration and definition are consistent; in compilation errors, “conflicting types for ‘xxx'” requires checking whether the function declaration and definition types are consistent, “expected ‘;’ before ‘xxx'” requires checking for missing semicolons, “unknown type name ‘xxx'” requires checking whether the type is defined or the corresponding header file is included; in warnings, “implicit declaration of function ‘xxx'” requires declaring the function before use, “unused variable ‘xxx'” requires deleting unused variables or using (void) xxx; to avoid warnings. Understanding the essence of these errors can help locate and resolve issues faster, improving programming efficiency.
3.3 Using Debugging Tools
Debugging tools are powerful weapons for troubleshooting errors. Tools like GDB (GNU Debugger) are widely used in Linux systems. When using GDB for debugging, you first need to add the -g option during compilation, which will add debugging information to the executable file. For example, gcc -g -o test test.c. Then use the gdb command to start debugging. After entering the debugging environment, you can set breakpoints using the break command to pause the program at a specified line, and then use the run command to run the program, which will stop at the breakpoint. At this point, you can use the print command to view the value of variables, such as print num to check the value of the variable num. You can also use the next command to step through the code line by line to find logical errors. In Windows systems, if you use Visual Studio for development, it comes with powerful debugging features. You can set breakpoints by clicking in the blank area to the left of the code line, and then click the debug button (usually a green triangle) to start debugging. You can also view variable values, step through the code, etc., to help quickly locate errors.
(1) Complete Example of Using GDB to Debug C Language Programs
#include <stdio.h>
#include <stdlib.h>
// Calculate the average of array elements
float calculate_average(int *array, int size) {
if (size <= 0) {
printf("Error: Array size must be greater than 0\n");
return 0.0;
}
int sum = 0;
for (int i = 0; i <= size; i++) { // There is a bug here: should be i < size
sum += array[i];
}
return (float)sum / size;
}
// Find the maximum value in the array
int find_max(int *array, int size) {
if (size <= 0) {
printf("Error: Array size must be greater than 0\n");
return -1;
}
int max_value = array[0];
for (int i = 1; i < size; i++) {
if (array[i] > max_value) {
max_value = array[i];
}
}
return max_value;
}
// Calculate the sum of squares of array elements
int calculate_square_sum(int *array, int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += array[i] * array[i];
}
return sum;
}
int main() {
int numbers[] = {10, 20, 30, 40, 50};
int size = sizeof(numbers) / sizeof(numbers[0]);
printf("Array elements:");
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
float average = calculate_average(numbers, size);
printf("Average: %.2f\n", average);
int max = find_max(numbers, size);
printf("Max value: %d\n", max);
int square_sum = calculate_square_sum(numbers, size);
printf("Sum of squares: %d\n", square_sum);
return 0;
}
(2) Compilation and Debugging Steps
Compile the program (add debugging information)
gcc -g -o array_analysis array_analysis.c
Start GDB debugging
gdb ./array_analysis
Common GDB debugging command examples
# Set breakpoints
(gdb) break main # Set breakpoint at the start of main function
(gdb) break calculate_average # Set breakpoint in calculate_average function
(gdb) break 15 # Set breakpoint at line 15
# View breakpoint information
(gdb) info breakpoints
# Run the program
(gdb) run
# Step through (do not enter function)
(gdb) next
(gdb) n # Abbreviation
# Step through (enter function)
(gdb) step
(gdb) s # Abbreviation
# View variable values
(gdb) print size # Print the value of variable size
(gdb) p sum # Print the value of variable sum
(gdb) p array[i] # Print array element
# Set variable watchpoint
(gdb) watch sum # Pause when the value of sum changes
# Continue execution to the next breakpoint
(gdb) continue
(gdb) c # Abbreviation
# View current code
(gdb) list
(gdb) l # Abbreviation
# View function call stack
(gdb) backtrace
(gdb) bt # Abbreviation
# Exit debugging
(gdb) quit
(gdb) q # Abbreviation
(3) Debugging Session Example
$ gdb ./array_analysis
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
...
Reading symbols from ./array_analysis...done.
(gdb) break main
Breakpoint 1 at 0x11a9: file array_analysis.c, line 41.
(gdb) run
Starting program: /home/user/array_analysis
Breakpoint 1, main () at array_analysis.c:41
41 int main() {
(gdb) next
43 int numbers[] = {10, 20, 30, 40, 50};
(gdb) next
44 int size = sizeof(numbers) / sizeof(numbers[0]);
(gdb) print size
$1 = 5
(gdb) break calculate_average
Breakpoint 2 at 0x1129: file array_analysis.c, line 7.
(gdb) continue
Continuing.
Array elements: 10 20 30 40 50
Breakpoint 2, calculate_average (array=0x7fffffffe170, size=5) at array_analysis.c:7
7 float calculate_average(int *array, int size) {
(gdb) next
9 if (size <= 0) {
(gdb) next
14 int sum = 0;
(gdb) next
15 for (int i = 0; i <= size; i++) { // Here is a bug: should be i < size
(gdb) print size
$2 = 5
# Found the problem: The loop condition should be i < size, not i <= size
# This will cause out-of-bounds access
(gdb) quit
A debugging session is active.
(4) Corrected Code
float calculate_average(int *array, int size) {
if (size <= 0) {
printf("Error: Array size must be greater than 0\n");
return 0.0;
}
int sum = 0;
for (int i = 0; i < size; i++) { // Fix: i < size
sum += array[i];
}
return (float)sum / size;
}
In Visual Studio debugging:
- Set breakpoints: Click in the blank area to the left of the code line
- Start debugging: Press F5 or click the green triangle button
- Step through: F10: Step through (do not enter function), F11: Step through (enter function).
- View variables: Use the “Local Variables” window or right-click the variable to select “Add Watch”
- Continue execution: Press F5 to continue to the next breakpoint
With these debugging tools and techniques, you can effectively locate and resolve various errors in C language programs.