Question

I'm trying to translate my console log with gettext, but I get the follow error:

program.c: In function ‘program_take_screenshot’:
program.c:55:14: error: expected ‘)’ before ‘dcgettext’
 #define _(x) gettext(x)
              ^
program_logger.h:117:49: note: in definition of macro ‘PROGRAM_ERR’
       fprintf(LOG_FILE, "Program [ERROR] :: " __VA_ARGS__); \
                                                 ^
program.c:173:17: note: in expansion of macro ‘_’
       PROGRAM_ERR(_("Cannot take screenshot. GPU rendering is used and read_viewport is not supported.\n"));
                 ^

what I do wrong?

definition in program_logger.h:

#define PROGRAM_LOG(...) do { \
      if (PROGRAM_LOG_VERBOSE) \
      { \
         fprintf(LOG_FILE, "Program: " __VA_ARGS__); \
         fflush(LOG_FILE); \
      } \
   } while (0)

definition of PROGRAM_ERR:

#define PROGRAM_ERR(...) do { \
      fprintf(LOG_FILE, "PROGRAM [ERROR] :: " __VA_ARGS__); \
      fflush(LOG_FILE); \
   } while (0)
Was it helpful?

Solution

Although one of the other answers explains what's going on, it doesn't give you an appropriate means of solving the problem.

What you had:

#define PROGRAM_ERR(...) do { \
      fprintf(LOG_FILE, "PROGRAM [ERROR] :: " __VA_ARGS__); \
      fflush(LOG_FILE); \
   } while (0)

would allow, for example, using it like PROGRAM_ERR("some error: %s", "error message"). Yet as you've found, PROGRAM_ERR(_("some error: %s"), "error message") fails.

The cause is, as explained already, indeed that this expands to

do { fprintf(LOG_FILE, "PROGRAM [ERROR] :: " _("some error: %s"), "error message"); fflush(LOG_FILE); } while(0)

and string concatenation only works for string literals.

In my opinion, the simplest way to make this work, is

#define PROGRAM_ERR(...) do { \
      fputs("PROGRAM [ERROR] :: ", LOG_FILE); \
      fprintf(LOG_FILE, __VA_ARGS__); \
      fflush(LOG_FILE); \
   } while (0)

By separating the two strings, you don't need any compile-time string concatenation, which is simply not possible if the strings are not known at compile-time.

OTHER TIPS

Try changing the macro to put ## before __VA_ARGS__. (##__VA_ARGS__) That instructs the preprocessor to place a comma there, but only if there is an argument.

See the gcc documentation here for more details.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top