It can increase memory usage, for both RAM and program code.
Structure padding
Most architectures require that variables are somehow aligned. For example 32-bit variables may have to be aligned to addresses divisible by 4 to have efficient access.
Structure members are required to be in order they are declared. This means that compilers may need to add padding to keep data access fast.
struct { // Structure aligment is 4, to keep 'a' aligned
uint32_t a;
uint8_t b;
// Compiler inserts 3 byte padding here to keep 'c' aligned
uint32_t c;
//... other data here
} Module;
Compilers can arrange "free" variables in memory in a way that is space efficent. For structures you need to do this manually. Usually this is done by ordering members from largest to smallest, or opposite.
Note that structre packing that many compilers offer is not solution for this. It typically decreases performance and/or increases program size.
Variable placement
I am simplifying this but:
Typically globals are divided in 2 groups: zero initialized and value initialized (other than zero). Before starting main, these both have to be initialized.
For zero initialized variables linker typically just groups them together in one location, and then does one big memset
to set all bytes to zero in that area before calling main function.
Value initialized variables are similarly grouped in other location and then at program startup one big memcpy
is done to copy initial values from program memory (arranged in same order) on your variables.
If you combine all variables to struct, then you are forcing all initial values to be copied from program memory if any of the values is non-zero.
If you are on desktop machine, these might not be problem. However, on embedded system where memory is tight, these have to be taken into consideration.
Note that I am not saying that this is a bad idea. Just keep structures modular too and avoid massive monolith structures.