5

I'm using Visual C++ to compile my plug-in for Cinema 4D.

    GeDebugOut("-->");
    subroot = NULL;
    head = NULL;
    tail = NULL;
    success = PolygonizeHierarchy(source, hh, head, tail, &subroot, malloc);
    if (!success) {
        /* .. */
    }
    String str("not set.");
    if (subroot) {
        GeDebugOut("yes");
        str = "yes!";
        GeDebugOut("Subroot name: " + subroot->GetName());
    }
    else {
        GeDebugOut("no");
        str = "no!";
    }
    GeDebugOut("Is there a subroot?   " + str);
    GeDebugOut("<--");

The expected output is the following:

-->
yes
Subroot name: Cube
Is there a subroot?  yes
<--

(or the same with "no" instead.) But I get

-->
yes
<--


Why are two prints missing here?


This is the declaration of GeDebugOut.

void GeDebugOut(const CHAR* s,  ...);
void GeDebugOut(const String& s);

The String class is concatenateable. It overloads the + operator.

String(void);
String(const String& cs);
String(const UWORD* s);
String(const CHAR* cstr, STRINGENCODING type = STRINGENCODING_XBIT);
String(LONG count, UWORD fillch);
friend const String operator +(const String& Str1, const String& Str2);
const String& operator +=(const String& Str);
Niklas R
  • 16,299
  • 28
  • 108
  • 203
  • How is `GeDebugOut` declared? – jxh Jul 25 '12 at 15:41
  • 1
    Is `String` a typedef for `std::string`? – jxh Jul 25 '12 at 15:46
  • 1
    It looks like the overload of `GeDebugOut` for `String` isn't working properly. Have you tested that? – Mike Seymour Jul 25 '12 at 15:47
  • @NiklasR: I think Unicode is enabled. In that case, you need to use `L"string literal"`. See my answer. – Nawaz Jul 25 '12 at 15:55
  • 2
    @MikeSeymour Omg.. How did you find out? I would never have had that idea, lol.. I can do `GeDebugOut("foobar")` and it works fine. But `GeDebugOut(String("foobar"))` doesn't print anything. Sorry to everyone and thanks for their answers. :D – Niklas R Jul 25 '12 at 16:01
  • @NiklasR: In that case, the workaround is just, as I said, use `%s` like you use in `printf`. – Nawaz Jul 25 '12 at 16:05

3 Answers3

5

You need to use GeDebugOut like you use printf:

GeDebugOut("Some message =  %s ", whatever);

where whatever is a c-string, i.e its type is char*.

Since an overload of GeDebugOut accepts String type also, then I think you need to use unicode as:

GeDebugOut(L"Is there a subroot?   " + str);
        // ^ note this!

because my suspicion is that if unicode is enabled, then CHAR is basically wchar_t, not char. And because of this, the string concatenation doesn't work, as the string-literal doesn't implicitly get converted into String type, to be passed to + overload.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Oh, good to know. But the application crashes now, I guess because it expects `char*` and I pass String. But the `String` class is concatenateable, so why shouldn't it work this way? – Niklas R Jul 25 '12 at 15:44
  • Please also see my edit which includes the declaration of `GeDebugOut` – Niklas R Jul 25 '12 at 15:46
  • @NiklasR: `whatever` should be a c-string. – Nawaz Jul 25 '12 at 15:46
  • 2
    You have GeDebugOut() takes in `char*`, When you pass it the string literal, it chooses that one, so your `+` is doing pointer arithmetic instead of string concatenation, especially if `String` has a conversion to `char*`. – JohnMcG Jul 25 '12 at 15:47
  • @JohnMcG: You'd only get pointer arithmetic here if `String` had a conversion to a numeric type. You can't add two pointers, so a conversion to `char*` wouldn't be considered. – Mike Seymour Jul 25 '12 at 16:01
  • This sample program:int main() { char* p1, p2; char* p3 = p1 + p2; return 0; } compiles in gcc. – JohnMcG Jul 25 '12 at 16:05
  • 1
    @JohnMcG: `p2` is `char`, not `char*`. Try this : `char *p1, *p2; char* p3 = p1 + p2;` – Nawaz Jul 25 '12 at 16:08
  • @Nawaz Yup, did another one with conversion operators that didn't work. – JohnMcG Jul 25 '12 at 16:09
1

You cannot append a string to a string literal.

"Is there a subroot" is a string literal and the compiler will see the use of it as a pointer to that literal.

A better way would be to do:

GeDebugOut("Is there a subroot? %s ", str);
Man of One Way
  • 3,904
  • 1
  • 26
  • 41
1

As you mentioned, there are two versions of GeDebugOut the compiler can choose from:

void GeDebugOut(const CHAR* s,  ...);
void GeDebugOut(const String& s);

when it encounters:

GeDebugOut("Is there a subroot?   " + str);

"Is there a subroot" is a string literal, which translates to type const char*. I suspect String has a conversion operator to some numeric type. So the compiler is choosing the first overload.

This is resulting in behavior you're not expecting, because the + operation for const char* is pointer arithmetic, not string concatenation, so you're calling GeDebugOut on the pointer sum of your string literal, and whatever the output of that const char* conversion of str is.

There's several ways you can correct this. As another mentioned, you can change it to printf-like syntax. Or you can force it to use the String overlaod like so:

GeDebugOut(String("Is there a subroot?") + str);
JohnMcG
  • 8,709
  • 6
  • 42
  • 49
  • Edited to note after being corrected that compiler will not allow arithmetic between pointer variables, though it seems less likely that `String` would be convertable to a numeric type, so my suspicion seems less valid. – JohnMcG Jul 25 '12 at 16:12