0

It seems to be very simple, but I can't figure it out. Here is question: I have a simple function that returns a string:

const wchar_t* getCompanyName() { return L"Test Company";};

I want to define a macro like the following:

#define COMPANY getCompanyName();
#define PRODUCT COMPANY L" in Canada"

const wchar_t * company = COMPANY; 
const wchar_t * product = PRODUCT; 

I would expect to see the "product" value is "Test Company in Canada", but it only shows "Test Company" and string "in Canada" never concat to the product string

Thank you so much for your time, here is the full code:

#include <stdio.h>
#include <tchar.h>

const wchar_t* getCompanyName() { return L"Test Company";};
#define COMPANY getCompanyName();
#define PRODUCT COMPANY L" in Canada"

int _tmain(int argc, _TCHAR* argv[]) {
    const wchar_t * company = COMPANY; // get Test Company
    const wchar_t * place = PRODUCT; // get Test Company in Canada

    wprintf(company);
    wprintf(place);

    return 0;
}

2 Answers2

3

Because of

#define COMPANY getCompanyName();

Remove the semicolon:

#define COMPANY getCompanyName()

To elaborate, the way you have it written:

const wchar_t * product = PRODUCT;

expands into:

const wchar_t * product = getCompanyName(); L" in Canada";

The

L" in Canada";

is a fine expression on its own that does nothing. Morale of the story: be careful with semicolons in macros, usually they are not necessary, but sometimes they may be.

Max
  • 3,384
  • 2
  • 27
  • 26
  • In the expansion of PRODUCT to `getCompanyName() L" in Canada". (`prog.cpp:5:25: error: expected ‘,’ or ‘;’ before string constant`) http://ideone.com/PcP1ph – rici Oct 07 '13 at 00:44
  • So you're trying to concat the result of a function with a string literal. –  Oct 07 '13 at 00:48
  • 1
    Yes, it is a syntax error. If you want to concatenate two strings in C, you must use either `strncat`, or similar function, or string objects in C++. – Max Oct 07 '13 at 00:50
  • You may only concatenate two static strings the way you were trying. Try `#define COMPANY L"Test company"` and then it will work. – Max Oct 07 '13 at 00:51
  • #define COMPANY L"Test company" - yes, it works. But I need the COMPANY to be a function since it needs to return a system runtime value. – user2852910 Oct 07 '13 at 00:56
  • Look up string concatenation in C. For instance: http://stackoverflow.com/questions/308695/c-string-concatenation – Max Oct 07 '13 at 00:59
  • thanks again for the reference - the strcat function can do the job for sure. But, it will require to the change the macro #define PRODUCT COMPANY L" in Canada". – user2852910 Oct 07 '13 at 01:03
  • @Max - `strncat` is not suitable for most situations. It will quietly give you a string without a nul terminator if the size of the target array is the same as the number of characters to be copied. So, indeed, use a **similar** function, i.e., `strcat`. – Pete Becker Oct 07 '13 at 12:45
  • @user2852910 - `strcat` isn't quite right; the code is dealing in wide-character strings, so it needs `wcscat`. – Pete Becker Oct 07 '13 at 12:46
  • @PeteBecker: this is off the topic of the question. You are wrong about `strncat`, it will always append a 0 byte to the end of the buffer. You may end up with a truncated string. But `strcat` has deeper problems where it can cause your buffer to overflow. Both are horrible (C strings suck), but `strncat` is at least better than `strcat`. In any case, this is off-topic and ask another question if you would like to discuss this more. – Max Oct 07 '13 at 14:26
  • @PeteBecker: Maybe what I said is not a standard. `strncat` behaves this way according to Posix: http://pubs.opengroup.org/onlinepubs/009695399/functions/strncat.html but maybe it is different on other platforms. – Max Oct 07 '13 at 14:30
  • @Max - whoops, sorry; I was thinking of `strncpy`. `strncat` always appends a nul character. – Pete Becker Oct 07 '13 at 14:39
2

String concatenation only works between adjacent literal strings. You can do this:

const w_char* product = L"This is " "a concatenated string " "constant.";

But not this:

const char* first = "First";
const char* second = first " Second";

So you definitely can't concatenate a literal string to the result of calling a function. And:

#define COMPANY getCompanyName()

does not call getCompanyName and insert it's value into the macro. It just makes COMPANY a synonym for getCompanyName().

So PRODUCT (even removing the ; from COMPANY) will expand to

getCompanyName() L" in Canada."

which is a syntax error.

rici
  • 234,347
  • 28
  • 237
  • 341
  • thank for the comments, makes sense. how to make the macro work - to concat the function returned string value? – user2852910 Oct 07 '13 at 00:54
  • @user2852910: You can't do it with a macro. You need to actually write a function. If you're actually using C++ and not C, then use `std::wstring` and you can concatenate two strings with the `+` operator. That's way easier than C. – rici Oct 07 '13 at 00:59
  • getCompanyName() L" in Canada." is a syntax error, how to fix it and make it work? the ';' will compile, but does not work as we already know – user2852910 Oct 07 '13 at 01:09
  • @user2852910: If you were using C++ and getCompanyName() returned a std::wstring, then you could define `PRODUCT` as `COMPANY + L" in Canada"`. But I think that requires quite a lot of modification to your program, too. In any event, the question you are now asking is very different from the original one, and you might want to try to ask a new question, after thinking through the alternatives a bit. – rici Oct 07 '13 at 01:19