Using MSVC preprocessor 'charizing' operator in Clang - c++

I've got the following code that someone working on MSVC has given to me:
#define MAP1(x, y) map[#x] = ##y;
I'm on Xcode, using Clang, and from various google searches I've found that this is known as a 'charizing operator', and is specific to MSVC's preprocessor. Is there a way of emulating the functionality of this operator while using Clang? I've tried removing the # but got the following error message:
Assigning to 'int' from incompatible type 'const char[2]'
Would an explicit cast to 'int' work or is the charizing operator doing something different?

The stringizing operator (standard C++) converts a into "a", so the charizing operator sounds like it turns a into 'a'. You can, in the simple cases, get 'a' from "a" by taking the first character.
#define MAP1(x, y) map[#x] = static_cast<const char(&)[2]>(#y)[0];
The static_cast to const char(&)[2] ensures you get a compile-time error if you don't get a string of length 1, which is two characters if you count the trailing '\0'. A plain #y[0] would silently take the first character, regardless of the string's length.

Did you try something like #y[0]? Basically, "stringify y and take the first char" :-)
Other than that, since from the looks of it the generated statements are executed at runtime anyway, you can just stringify y, pass it to a function and have that function return the right thing.

Related

Using macros in printf function in VS2013 vs VS2017

I have defined this macro in my source code
#define UINT_08X_FORMAT "%08X"
I need to use the above in printf like this:
printf("Test - "UINT_08X_FORMAT"", 50);
It compiles and works fine in VS2013 where as in VS2017, it throws the following compile error.
invalid literal suffix 'UINT_08X_FORMAT'; literal operator or literal
operator template 'operator ""UINT32_FORMAT' not found
How to use the macro in printf.
Note: I dont want to change the macro definition as it works fine with
VS2013. I need a common solution which will work on both VS2013 and
VS2017.
C++11 added support for user defined literals (UDL), which are triggered by adding a suffix to some other literal (in this case a string literal). You can overcome it by adding spaces around your macro name to force the newer C++ compiler to treat it as a separate token instead of a UDL suffix:
printf("Test - " UINT_08X_FORMAT "", 50);
See this note from http://en.cppreference.com/w/cpp/language/user_literal:
Since the introduction of user-defined literals, the code that uses
format macro constants for fixed-width integer types with no space
after the preceding string literal became invalid:
std::printf("%"PRId64"\n",INT64_MIN); has to be replaced by
std::printf("%" PRId64"\n",INT64_MIN);
Due to maximal munch, user-defined integer and floating point literals
ending in p, P, (since C++17) e and E, when followed by the operators
+ or -, must be separated from the operator with whitespace in the source

Will bitshift and arithmetic operations be evaluated by the precompiler?

If I define the following in a C++98 program:
#define BITS_PER_FOO 2
#define BITS_PER_BAR 3
#define FOOBARS (1<<(BITS_PER_FOO*BITS_PER_BAR))
then will FOOBARS get evaluated as 64 by the precompiler? Or will a multiplication and bit-shift operation take place at each location that I use FOOBARS in the code?
No, since it's not the preprocessor's business. It does the usual replace thing, not constant folding.
However, any reasonable compiler will do constant folding, so you should not expect this to correspond to instructions being executed at runtime.
The precompiler just does text substitution - it's essentially copy & paste on steroids. This means that the expression you wrote for FOOBAR will be expanded in full at each replacement location.
Now, any decent compiler will evaluate that whole subexpression at compile time anyway. However, you can save it some work (and have some extra advantages, like having a clear type of your expression, clearer diagnostic, less surprises deriving from substitutions in the wrong places, and having an actual lvalue for your constants instead of expressions) by defining these values as actual constants, like:
const int bits_per_foo = 2;
const int bits_per_bar = 3;
const int foobars = 1<<(bits_per_foo*bits_per_bar);
A multiplication and bit-shift operation will take place at each location that you use FOOBARS.
See: #define Directive (C/C++)
#define forms a macro, meaning the identifier is replaced with everything in the token-string. In your case, the preprocessor replaces instances of FOOBARS with the expression (1<<(BITS_PER_FOO*BITS_PER_BAR))

Explain the difference:

int i=1,2,3,4; // Compile error
// The value of i is 1
int i = (1,2,3,4,5);
// The value of i is 5
What is the difference between these definitions of i in C and how do they work?
Edit: The first one is a compiler error. How does the second work?
= takes precedence over ,1. So the first statement is a declaration and initialisation of i:
int i = 1;
… followed by lots of comma-separated expressions that do nothing.
The second code, on the other hand, consists of one declaration followed by one initialisation expression (the parentheses take precedence so the respective precedence of , and = are no longer relevant).
Then again, that’s purely academic since the first code isn’t valid, neither in C nor in C++. I don’t know which compiler you’re using that it accepts this code. Mine (rightly) complains
error: expected unqualified-id before numeric constant
1 Precedence rules in C++ apply regardless of how an operator is used. = and , in the code of OP do not refer to operator= or operator,. Nevertheless, they are operators as far as C++ is concerned (§2.13 of the standard), and the precedence of the tokens = and , does not depend on their usage – it so happens that , always has a lower precedence than =, regardless of semantics.
You have run into an interesting edge case of the comma operator (,).
Basically, it takes the result of the previous statement and discards it, replacing it with the next statement.
The problem with the first line of code is operator precedence. Because the = operator has greater precedence than the , operator, you get the result of the first statement in the comma chain (1).
Correction (thanks #jrok!) - the first line of code neither compiles, nor is it using the comma as an operator, but instead as an expression separator, which allows you to define multiple variable names of the same type at a time.
In the second one, all of the first values are discarded and you are given the final result in the chain of items (5).
Not sure about C++, but at least for C the first one is invalid syntax so you can't really talk about a declaration since it doesn't compile. The second one is just the comma operator misused, with the result 5.
So, bluntly, the difference is that the first isn't C while the second is.

String compare in c++

What is the difference between (x == "x") and ("x" == x) comparison in C++? Let's say x is a std::string. Is there any reason why one would be preferred over the other?
One is a string literal "X", and the other is an instance of std::string. Some advocate having the constant "x" on the left hand side, because that way you would get a compiler error if you use assignment = instead of equality ==:
if ("x" = x) // Error! Trying to assign to const char[]
if (x = "x") // Setting the value of x to be "x", and evaluating "x".
// Probably not what you want.
Other than that, there's really no difference.
I think both calls will result in call to bool std::string operator==(const std::string&, const std::string&).
This is because there are no implicit conversion operators from std::string to const char*, but there is implicit constructor from const char* to std::string.
EDIT:
on g++ 4.4.5 both comparisons works.
Here says the now closed question on Yoda Conditionals:
This is one of the things that I hate
most when I see it in someone else's
code. I know what it means and why
some people do it this way ("what if I
accidentally put '=' instead?"). For
me it's very much like when a child
goes down the stairs counting the
steps out loud.
Anyway, here are my arguments against
it:
It disrupts the natural flow of reading the program code. We, humans,
say "if value is zero" and not "if
zero is value".
Modern compilers warn you when you have an assignment in your condition,
or actually if your condition consists
of just that assignment, which, yes,
looks suspicious anyway
You shouldn't forget to put double '=' when you are comparing values if
you are a programmer. You may as well
forget to put "!" when testing
non-equality.
-mojuba
Accepted answer:
Ah, yes, "Yoda conditionals" ("If zero
the value is, execute this code you
must!"). I always point anyone who
claims they're "better" at tools like
lint(1). This particular problem has
been solved since the late 70s. Most
modern languages won't even compile
this, as they refuse to coerce the
result of the assignment to a boolean.
As others have said, it certainly
isn't a problem, but it does provoke a
bit of cognitive dissonance.
-TMN
I prefer using for NSStrings...
([x isEqualToString:#"x"])
or for c strings
strcmp(str1,str2);
There is no difference between those two conditions, other than maybe something internal. It's like holding two things in your hands, one in each hand, and comparing them - and then basing then factoring in which hand each one is in. ...That's not something that's a factor.

How to fix C++ warning of implicit conversion?

I am just getting started in C++.
I am trying to get the first three characters of the string 'str', and compare it to a known string, say, 'knownString'.
To do that, I wrote this line of code:
if (str.substr(start, 3) == knownString)
where 'start' is an integer I declared before.
But I keep getting this warning message:
warning: implicit conversion changes signedness: 'int' to
'std::__cxx11::basic_string,**
**std::allocator >::size_type' (aka 'unsigned int')
Does anyone knows what I can add or I missed in this statement to fix this?
You can:
Either 1. make the conversion explicit:
str.substr(static_cast<std::string::size_type>(start), 3)
Or 2. not make a conversion in the first place:
std::string::size_type start;
Or 3. ask compiler to not warn about it:
g++ compilation arguments -Wno-sign-conversion
I recommend option 2.
This warning is triggered by the -Wsign-conversion switch, detecting that you're taking a signed variable and converting it to an unsigned variable, in a way that may change the value.
It doesn't do it for positive literals, where the conversion obviously doesn't change the value, because that would be pointless and really annoying. You'll get it for a negative literal like -5.
(Technically, this is the literal 5 with the unary negation operator applied, not a "negative literal"!).
For named variables it can't really predict what the value would be, so errs on the side of caution.
You should make your variable start have type size_t.