Me? I'ld take "#define SECTOR_SIZE (512)" any day.... but that you never know, it might grow on me.
Well yeah, that works. One practical reason against macro constants is that they're unknown to your debugger, since they get stripped away before the compiler. Macros are also sloppy when it comes to strong typing.
Frequently, I'll use enums in an API when I want to make sure that an argument to a function/method has a limited range of values and enforce that at compile time. ints are, well, integers, and force you to check stuff at runtime (if at all).
Truth be told, I spend most of my time in C++ and depend heavily on compile-time type checking to keep me out of the weeds. Things like strongly type enums and 'const' (did I just hear a gasp from the back row?) flush a lot of problems out before I fire up the J-Link.
And my static constexpr function can beat up your #define expansion any day of the week. ;-)
The pre-processor is the part of the C language.
Is it really? The C standard is pretty specific about how expressions are evaluated. E.g., what something like "a+b" means when the types of the identifiers are specified. But when you don't know those types, the standard won't have much to say.
I've got a special rule in most of my makefiles that produces the preprocessed output only (i.e., no object code) specifically for tracking down goofy things that happen with macros:
$(BUILD)/%.E : %.c | $(BUILD)
@echo Compiling $(subst $(ABS_ROOT),,$(<))
@$(CC) $(CFLAGS) -E -c $< -o $(@)
I like the preprocessor for #include, #pragma once and X-macros, but constants and inline functions are better handled (IMO) by constants in the language itself and inline functions.
...
I'll confess that I've been abusing the preprocessor on a recent project though. Some of the code is automatically generated (CubeMX) and the generated main() conflicts with mine, causing the linker to complain.
But the preprocessor can get around this by changing function names from the outside. Another gnu makefile snippet:
$(OBJ)/$(BOARD)/cubemx/Src/main.o : CFLAGS += -Dmain=cubemx_generated_main
That defines "main" to be a macro that evaluates to some other name, but just for the compilation of that one specific file. It requires a target-specific variable definition in the Makefile, which I'm sure crosses a line.
But it's a lot easier than having to sed the output.