-2

My iprintf function repeats the same string e.g.:

iprintf("[USER] created user:%d", userID);
iprintf("[USER] user disconnected:%d, userID");

I am trying to save some space and do something like this

const char strUser[] = "[USER]";
iprintf(strUser + "created user:%d", userID);
iprintf(strUser + "user disconnected:%d", userID);

What in C language can replace the "+" so it will work?

I am trying to keep at least part of the string as a parameter.

And do it during compilation with no extra functions

susanth29
  • 356
  • 1
  • 2
  • 17
schanti schul
  • 681
  • 3
  • 14

1 Answers1

2

If and how much space any attempt at optimization saves depends on the compiler. There is usually an option for a "minimum size build". Compiling the program and checking the results is the only method to see if space was truly saved. There is a good chance that any compiler, aiming for a minimum size build, that sees const char strUser[] = "[USER] "; will create exactly one string in the program, and point to that string wherever it is used.

Here are three options you could try. One using a macro, one using a function, and one using a different function call. I know you asked for "during compilation with no extra functions", but this function may very well be "optimized away" during compilation.

#include <stdarg.h>
#include <stdio.h>
#include <string.h>

// warning: ISO C does not permit named variadic macros
#define IPRINTF1(format, args...) printf("[USER] " format, ##args);

// An iprintf wrapper that first prints the desired string.
void iprintf2(const char *restrict format, ...)
{
    printf("[USER] ");

    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
}

int main(void)
{
    const int userID = 5;
    const char strUser[] = "[USER] ";

    IPRINTF1("created user:%d\n", userID);
    iprintf2("created user:%d\n", userID);

    // Passing the string as an additional parameter.
    // This may be the best solution code quality-wise, as it avoids repetition while keeping the code dynamic.
    printf("%screated user:%d\n", strUser, userID);
}

Actually concatenating two strings with + as in Python is not possible in C. Instead there is the strcat function. However, this involves allocating a buffer that is large enough, making a copy of the format string, always guaranteeing that the restrict qualifier holds... This is almost certainly not worth it.

Also, this is all under the assumption that saving a couple of bytes is worth the decrease in code quality.

Yun
  • 3,056
  • 6
  • 9
  • 28
  • Thanks, I can't figure out why const char strUser[] = "[USER] " is better than const char* strUser = "[USER]" ? The latter show no difference in size in my project... – schanti schul Aug 15 '21 at 14:23
  • And won't IPRINTF1 replaced everywhere will add "[USER] " to all those places? – schanti schul Aug 15 '21 at 14:27
  • @schantischul Using `[]` creates the (short) string on the stack and makes it part of the code (`movabs rax, 9109807186531675`) which may be slightly smaller than putting it in a read-only data segment and referring to that. But again, this depends on the compiler. You may want to play around with [Compiler Explorer](https://godbolt.org) to see what the effect is. You may also want to read [this](https://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s). – Yun Aug 15 '21 at 14:45
  • @schantischul Yes, the _preprocessor_ will copy the "[USER] " string literal everywhere the macro is used, but it is very likely that the compiler will afterwards notice that the same string appears in multiple places and will optimize this. – Yun Aug 15 '21 at 14:49
  • Thanks! But I am getting the weirdest behavior, I am passing the string as additional parameter. (%s) On replacing some strings, I've noticed the size of the code gets bigger instead of smaller... My optimization flag: -Og, how can this be explained..? – schanti schul Aug 17 '21 at 11:53
  • @schantischul What is "the weirdest behavior"? If necessary, open a new question with a minimal, reproducible example. – Yun Aug 17 '21 at 11:57