How to combine string literals with PRId32, PRIu64, etc.?

Suppose I need to print a formatted string using int32_t using the printf format specifier from <inttypes.h> .

 int32_t i = 0; printf("%" PRId32 "\n", i); 

If I try to do the same with wide characters in Visual C ++ 2013, this will not work:

 #define W_(val) L ## val #define W(val) W_(val) wprintf(L"%" W(PRId32) L"\n", i); 

error C2308: concatenation of inconsistent strings

How to combine wide format literals with conversion specifier macros?

+7
c macros string visual-c ++ unicode
source share
2 answers

The problem is twofold. First, as noted in rici, C99 and C ++ 11's answer, support has been added for combining narrow string literals and wide string literals, so you don't need to extend the narrow literal by adding L. Visual C ++ does not yet support this for C or C ++.

Since the compiler does not yet support this function, we should give libraries the opportunity to explicitly extend these string literals using a technique similar to the one in your answer. Unfortunately, we have defined these macros so that they can expand to several string literals. For example, PRId32 expands to "l" "d" .

It is valid, but it does not allow you to expand, because there is no way to add L to the second string literal (to make "d" in L"d" ). I'm afraid I see no way to make this work without (re) defining macros myself.

I discovered an internal error, so that if the compiler does not add support for concatenating mixed-width literals during preprocessing in the next release, we can revise these definitions to possibly expand them explicitly.

+5
source share

I know zip-all about VS C ++, but you really don't need the L prefix for concatenation and a wide string literal.

  L"%" PRId32 "\n" 

should work (and it works with gcc).

From the C11 project, & section 6.4.5 / 5: (as far as I can tell, this was about the same on C99, except that C99 did not have utf-8 literals.)

In phase 6 of the translation, multi-character character sequences specified by any adjacent character sequence and identically prefix literal line tokens are concatenated into a single multi-byte character sequence. If any of the tokens has an encoding prefix, the resulting multibyte sequence of characters is considered to have the same prefix; otherwise, treated as a literal character string. In different ways - prefix string literal markers can be combined, and if so, the processing of the received multibyte character sequence is determined by the implementation.

See also section 7.8.1 / 7 for an example:

 uintmax_t i = UINTMAX_MAX; // this type always exists wprintf(L"The largest integer value is %020" PRIxMAX "\n", i); 

A similar proposal appears in the C ++ 11 standard, section 2.14.5 / 13. (However, in C ++ 03, combining two or more string literals was not allowed.)

In translation phase 6, adjacent string literals are combined. If both string literals have the same encoding prefix, the resulting concatenated string literal has this encoding prefix. If one string literal does not have an encoding prefix, it is treated as a string literal of the same encoding prefix as the other & hellip;

Visual Studio does not seem to allow this form of literal concatenation.

+1
source share

All Articles