views:

136

answers:

5

It gives the error in the title about this piece of code:

string DDateTime::date2OracleDate(DATE Date)
{
    string s;
    s="TO_DATE('" + DateFormat("%d/%m/%Y",Date) + "','dd/MM/YYYY')";
    return s;
}

I don't understand how that is possible, no pointers involved....

EDIT:

string DDateTime::DateFormat(string sFormat,DATE Date)
{
    struct tm tmTemp;
    RipOf_AfxTmFromOleDate(Date, tmTemp);
    RipOf_AfxTmConvertToStandardFormat(tmTemp);
    char sFormatted[MAX_TIME_BUFFER_SIZE];
    strftime(sFormatted, MAX_TIME_BUFFER_SIZE, sFormat.c_str(), &tmTemp);
    return sFormatted;
}
+2  A: 

Your literal strings are char*. I am not sure what your string is, but replacing each quoted string with a constructed string should do it.

s=string("TO_DATE('") + DateFormat("%d/%m/%Y",Date) + string("','dd/MM/YYYY')"); 
Kate Gregory
Only one of them needs to be constructed, as the result of operator+ will be a string, which can then be added to the other. On the other hand, I'm not sure that it's defined which.
DeadMG
Maybe so, but leaving code behind that takes advantage of that is going to mess somebody up later. They'll split it into two lines or only use the last half of it or whatever and then not understand why it doesn't work any more. They'll even ask why the first (or last) is different and needs/doesn't need to be wrapped in the constructor. Being explicit about your intentions builds a nicer code base at very little cost - it's easier to type the 8 characters in both places than to work out which place can do without them, leaving a puzzle for future readers.
Kate Gregory
+1  A: 
s="TO_DATE('" + DateFormat("%d/%m/%Y",Date) + "','dd/MM/YYYY')";

means (to the compiler) that you are adding a const char* pointer to something else (possibly a char*?) returned by / converted from DateFormat, and then add to it another const char* pointer.

Try this to force your compiler to find the correct string overloads for operator+:

s=string("TO_DATE('") + DateFormat("%d/%m/%Y",Date) + "','dd/MM/YYYY')";
Péter Török
+2  A: 

The following should work better:

string DDateTime::date2OracleDate(DATE Date)
{
    string s = "TO_DATE('";
    s += DateFormat("%d/%m/%Y",Date);
    s += "','dd/MM/YYYY')";
    return s;
}
Amardeep
Now what is the *reason* why it fails? `string` seems to be a class - why does adding a pointer and a class result in a warning about adding two pointers? I'm lost on that error message.
Johannes Schaub - litb
@Johannes: The associativity of operator=() is right to left while the associativity of operator+() is left to right. So the first operation performed on the line is `"TO_DATE('" + DateFormat()` which has no operator+() defined.
Amardeep
@Amardeep still doesn't explain why it thinks `DateFormat` returns a pointer. It shouldn't convert the string to a pointer (because there is no built-in operator candidate for "pointer + pointer"). But maybe it does convert, because it doesn't matter anymore when the program is ill-formed anyway. I agree with your explanation (which i think is likely), but i thought it should have been part of your answer. Now that it's part of a comment i'm satisfied too though.
Johannes Schaub - litb
@Johannes: Hmmm, the `DateFormat()` function prototype returns string but the body of the function returns a `char *` so compiler would have to create a temporary string from that. Could RVO have kicked in here? Btw, good point-- I should have included the explanation in the answer. Programmers can be so lazy...
Amardeep
+3  A: 

The three strings you're trying to add are C-style strings; each is a pointer to the contents of the string. At least, I'm assuming that DataFormat returns a C-style string; it's not a standard function, so I don't know what it does.

In C++ you can't simply "add" two of these together to get a C++ string, since there's no way of knowing whether a char* is actually a string, or a pointer to some arbitrary data. You have to convert one of them into a std::string, then you can "add" C-style strings to that.

string s = "TO_DATE(";
s += DateFormat(whatever);
s += "','dd/MM/YYYY')";

or

string s = string("TO_DATE(") + DateFormat(whatever) + "','dd/MM/YYYY')";
Mike Seymour
+1  A: 

The probelm is only coming from the return type of DateFormat being char* - std::strings can normally be concatenated with string literals without any problem.

E.g. the following works:

std::string a, b;
b = "foo";
a = "literal" + b + "literal";

but the following will not work:

std::string a, b;
b = "foo";
a = "literal" + b.c_str() + "literal";

The only change required should be to convert the result from DateFormat to a std::string.

s="TO_DATE('" + std::string(DateFormat("%d/%m/%Y",Date)) + "','dd/MM/YYYY')";

Should do the trick.

Edit 1

Seeing that DateFormat returns string there should have been no problems concatenating literal + std::string + literal. So I'm stumped.

Edit 2

Following up after Amardeep's noticing that DateFormat actually returns a char* despite the signature suggesting otherwise (nice catch). I tested and it indeed appears no errors or warnings are raised, even compiling with -Wall and -Wextra on gcc, the function behaves as if it were simply defiend char*.

So my solution should still work for the initial reasons. (and there is no actual problem with concatenating string literals with std::string, the problem is only char* with string literals).

It would probably be a neater solution to fix the root of the problem - the bad return type of DateFormat by converting sFormatted to a std::string.

    return std::string(sFormatted);
Fish