# and ## Operators, Predefined Symbolic Constants, AssertionsIn C, the preprocessor offers several useful tools for manipulating source code before the actual compilation begins. Among these are the # and ## operators, predefined symbolic constants, and assertions. These tools enhance flexibility, readability, and debugging during the development process.
# and ## OperatorsThe # and ## operators are used in macro definitions to manipulate the arguments passed to the macro. They allow you to create more powerful and flexible macros.
# Operator (Stringizing Operator)The # operator is known as the stringizing operator. It converts the argument passed to the macro into a string literal.
#define MACRO_NAME(arg) "string" #arg "string"
#include <stdio.h>
#define STRINGIFY(x) #x
int main() {
printf("Macro as string: %s\n", STRINGIFY(Hello, World!)); // Prints: "Hello, World!"
return 0;
}
STRINGIFY(Hello, World!) converts the argument Hello, World! into a string literal "Hello, World!".x is surrounded by double quotes, transforming it into a string.## Operator (Token Pasting Operator)The ## operator is known as the token pasting operator or concatenation operator. It combines two tokens into a single token. This can be especially useful when generating complex code inside macros, where you need to concatenate multiple identifiers.
#define CONCATENATE(x, y) x ## y
#include <stdio.h>
#define CONCATENATE(x, y) x ## y
int main() {
int xy = 10;
printf("The value of xy: %d\n", CONCATENATE(x, y)); // Prints: The value of xy: 10
return 0;
}
CONCATENATE(x, y) combines the two tokens x and y into xy, which refers to the variable int xy = 10;.## operator concatenates the two arguments into a single token, effectively creating xy as a variable name.The C preprocessor defines several predefined symbolic constants that provide useful information about the environment in which the code is compiled. These constants are available without needing any additional definitions.
__LINE__: Expands to the current line number in the source file.__FILE__: Expands to the name of the current source file as a string.__DATE__: Expands to a string representing the date when the source file was compiled (e.g., "Sep 21 2021").__TIME__: Expands to a string representing the time when the source file was compiled (e.g., "10:45:12").__STDC__: Expands to 1 if the compiler conforms to the ANSI C standard.#include <stdio.h>
int main() {
printf("Line number: %d\n", __LINE__); // Prints the current line number
printf("File name: %s\n", __FILE__); // Prints the name of the current file
printf("Compilation date: %s\n", __DATE__); // Prints the date when compiled
printf("Compilation time: %s\n", __TIME__); // Prints the time when compiled
return 0;
}
__LINE__, __FILE__, __DATE__, and __TIME__ expand to relevant information about the compilation process.assert()Assertions are a way to test assumptions made by the programmer during development. An assertion verifies whether a given condition is true; if the condition evaluates to false, the program will terminate and print an error message. Assertions are commonly used for debugging and ensuring that certain conditions hold during runtime.
The assert() function is part of the <assert.h> library.
#include <assert.h>
assert(condition);
condition: This is the expression that should evaluate to true. If the expression is false, the program will abort.#include <stdio.h>
#include <assert.h>
int main() {
int x = 5;
assert(x == 5); // This will not cause any issue because x == 5 is true.
x = 10;
assert(x == 5); // This will terminate the program because x == 5 is false.
printf("This line will not be executed.\n");
return 0;
}
assert(x == 5) will check if x is equal to 5. If true, the program continues. If false, the program aborts, and an error message is displayed.x is 10), the program prints a message similar to:
Assertion failed: (x == 5), file program.c, line 9
Assertions can be disabled by defining the NDEBUG macro before including <assert.h>:
#define NDEBUG
#include <assert.h>
With NDEBUG defined, the assertions will be excluded from the compiled program, effectively making them no-ops.
| Concept | Description |
|---|---|
# Operator (Stringizing) |
Converts an argument into a string literal. |
## Operator (Concatenation) |
Concatenates two tokens into one. |
| Predefined Constants | Constants like __LINE__, __FILE__, __DATE__, and __TIME__ that give information about the compilation environment. |
assert() |
Used for debugging by ensuring that a given condition is true at runtime. If false, the program terminates. |
The # and ## operators provide powerful tools for manipulating macro arguments in C, enabling string conversion and token concatenation. Predefined symbolic constants offer valuable insights into the environment in which the code is compiled, and assertions help ensure that runtime conditions hold as expected during development. These tools help create more robust, maintainable, and error-free C code.
Open this section to load past papers