here is the question, what does str(X) become
#define str_(X) #X #define str(X) str_(X)
when X is a string? is it ""string"" or "\"string\""?
Well just giving it a try shows that it becomes "X", with quotes.
When you write ""string"", it doesn't make sense syntax wise because the first double-quote gets matched with the next double quote, and so on. Hence ""string"", gets interpreted as a empty string, followed by the identifier with name string, followed by another empty string. In your second example, you tell the interpreted to use the double-quote as a literal character and not a special character, hence "\"string\"", gets interpreted as a string which contains a double-quote followed by the characters in string, then followed by a literal double-quote.