How is the following macro definition resolved?
#define EMAIL_SERVER_ADAPTER_FATAL_ERROR MSB_RETURN_TYPE_FATAL_ERROR | 1
I mean, is it resolved to 1 or to MSB_RETURN_TYPE_FATAL_ERROR and why?
| has no special meaning in macros. The macro is resolved to
MSB_RETURN_TYPE_FATAL_ERROR | 1
which is bitwise OR of two values (MSB_RETURN_TYPE_FATAL_ERROR and 1).
The | in the macro has the same meaning as elsewhere in C and C++. It means bitwise or.
Presumable MSB_RETURN_TYPE_FATAL_ERROR is some numeric value (otherwise it won't compile, pretty much).
For arguments sake, we'll make it 0x100
So the following code:
return EMAIL_SERVER_ADAPTER_FATAL_ERROR;
will expand to:
return MSB_RETURN_TYPE_FATAL_ERROR | 1;
which in turn becomes:
return 0x100 | 1;
which in turn is the same as:
return 0x101;
Of course MSB_RETURN_TYPE_FATAL_ERROR is probably something other than 0x100 - but the principle still applies.
Macros are just text replacement, so
EMAIL_SERVER_ADAPTER_FATAL_ERROR
will be substituted for
MSB_RETURN_TYPE_FATAL_ERROR | 1
After that it is just numbers (i.e. plain bit-wise OR operation).
Related
I've ran into an issue here, and I can't figure out exactly what SAP is doing. The test is quite simple, I have two variables that are a completely different type as well as having two completely different values.
The input is an INT4 of value 23579235. I am testing the equality function against a string '23579235.43'. Obviously my expectation is that these two variables are different because not only are they not the same type of variable, but they don't have the same value. Nothing about them is similar, actually.
EXPECTED1 23579235.43 C(11) \TYPE=%_T00006S00000000O0000000302
INDEX1 23579235 I(4) \TYPE=INT4
However, cl_abap_unit_assert=>assert_equals returns that these two values are identical. I started debugging and noticed the 'EQ' statement was used to check the values, and running the same statement in a simple ABAP also returns 'true' for this comparison.
What is happening here, and why doesn't the check fail immediately after noticing that the two data types aren't even the same? Is this a mistake on my part, or are these assert classes just incorrect?
report ztest.
if ( '23579235.43' eq 23579235 ).
write: / 'This shouldn''t be shown'.
endif.
As #dirk said, ABAP implicitly converts compared or assigned variables/literals if they have different types.
First, ABAP decides that the C-type literal is to be converted into type I so that it can be compared to the other I literal, and not the opposite because there's this priority rule when you compare types C and I : https://help.sap.com/http.svc/rc/abapdocu_752_index_htm/7.52/en-US/abenlogexp_numeric.htm###ITOC##ABENLOGEXP_NUMERIC_2
| decfloat16, decfloat34 | f | p | int8 | i, s, b |
.--------------|------------------------|---|---|------|---------|
| string, c, n | decfloat34 | f | p | int8 | i |
(intersection of "c" and "i" -> bottom rightmost "i")
Then, ABAP converts the C-type variable into I type for doing the comparison, using the adequate rules given at https://help.sap.com/http.svc/rc/abapdocu_752_index_htm/7.52/en-US/abenconversion_type_c.htm###ITOC##ABENCONVERSION_TYPE_C_1 :
Source Field Type c -> Numeric Target Fields -> Target :
"The source field must contain a number in mathematical or
commercial notation. [...] Decimal places are rounded commercially
to integer values. [...]"
Workarounds so that 23579235.43 is not implicitly rounded to 23579235 and so the comparison will work as expected :
either IF +'23579235.43' = 23579235. (the + makes it an expression i.e. it corresponds to 0 + '23579235.43' which becomes a big Packed type with decimals, because of another rule named "calculation type")
or IF conv decfloat16( '23579235.43' ) = 23579235. (decfloats 16 and 34 are big numbers with decimals)
When I define this macro:
#define SQR(x) x*x
Let's say this expression:
SQR(a+b)
This expression will be replaced by the macro and looks like:
a+b*a+b
But, if I put a ++ operator before the expression:
++SQR(a+b)
What the expression looks like now? Is this ++ placed befor every part of SQR paramete? Like this:
++a+b*++a+b
Here I give a simple program:
#define SQR(x) x*x
int a, k = 3;
a = SQR(k+1) // 7
a = ++SQR(k+1) //9
When defining macros, you basically always want to put the macro parameters in parens to prevent the kind of weird behaviour in your first example, and put the result in parens so it can be safely used without side-effects. Using
#define SQR(x) ((x)*(x))
makes SQR(a+b) expand to ((a+b)*(a+b)) which would be mathematically correct (unlike a+b*a+b, which is equal to ab+a+b).
Putting things before or after a macro won't enter the macro. So ++SQR(x) becomes ++x*x in your example.
Note the following:
int a=3, b=1;
SQR(a+b) // ==> a+b*a+b = 3+1*3+1 = 7
++SQR(a+b) // ==> ++a+b*a+b ==> 4 + 1*4 + 1 = 9
// since preincrement will affect the value of a before it is read.
You're seeing the ++SQR(a+b) appear to increment by 2 since the preincrement kicks in before a i read either time, i.e. a increments, then is used twice and so the result is 2 higher than expected.
NOTE As #JonathanLeffler points out, the latter call invokes undefined behaviour; the evaluation is not guaranteed to happen left-to-right. It might produce different results on different compilers/OSes, and thus should never be relied on.
For C++ the right way to define this macro is to not use a macro, but instead use:
template<typename T> static T SQR( T a ) { return a*a; }
This will get right some horrible cases that the macro gets wrong:
For example:
SQR(++a);
with the function form ++a will be evaluated once. In the macro form you get undefined behaviour as you modify and read a value multiple times between sequence points (at least for C++)
A macro definition just replaces the code,hence it is generally preferable to put into parenthesis otherwise the code may replaced in a way you don't want.
Hence if you define it as :
#define SQR(x) ((x)*(x))
then
++SQR(a+b) = ++((a+b)*(a+b))
In your example, ++SQR(a+b) should be expanded as ++a+b*a+b.
So, if a == 3 and b == 1 you will get the answer 9 if the compiler evaluates it from left to right.
But your statement ++SQR(3+1) is not correct because it will be expanded as ++3+1*3+1 where ++3 is invalid.
In your preprocessor it evaluates to ++a+b*a+b. The right way is put brackets around each term and around the whole thing, like:
#define SQR(x) ((x)*(x))
Ok this might sound a little vague from the title, but that's because I have no idea how to word it differently. I'll try to explain what I mean: very often in certain libraries, the 'init' function accepts some parameters, but that parameter then accepts multiple parameters (right..). An example, would be like this:
apiHeader.h
#define API_FULLSCREEN 0x10003003
#define API_NO_DELAY 0x10003004
#define API_BLAH_BLAH 0x10003005
main.c:
apiInit(0, 10, 10, 2, API_FULLSCREEN | API_NO_DELAY | API_BLAH_BLAH);
How does this work? I can't find the answer anywhere, most likely because I don't know how it's actually called so I have no clue what to search for. It would be very useful in my current project.
Thanks in advance!
The parameter is usually called "$FOO flags" and the values are or-ed. The point is that the parameter is a numeric type that is constructed as the bitwise or of multiple possible values.
In the processing functions, the values are usually tested with a bitwise and:
if ( (flags & API_FULLSCREEN) != 0 )
You have to be careful to assign values in a way that keeps the OR operation linear. In other words, don't set the same bit in two different or-able values, like you did in your header. For example,
#define API_FULLSCREEN 0x1
#define API_NO_DELAY 0x2
#define API_BLAH_BLAH 0x4
works and allows you to deconstruct all combinations of flags in your function, but
#define API_FULLSCREEN 0x1
#define API_NO_DELAY 0x2
#define API_BLAH_BLAH 0x3
does not because API_FULLSCREEN | API_NO_DELAY == API_BLAH_BLAH.
Viewing from a higher level, a flags int is a poor man's variable argument list. If you consider C++, you should encapsulate such detail in a class or at least a std::bitset.
This fifth parameter is usually a mask. It works by defining several consts (probably an enum) with values that are powers of two, or combinations of them. Then they are encoded into a single value using |, and decoded using &. Example:
#define COLOUR_RED 0x01
#define COLOUR_GREEN 0x02
#define COLOUR_BLUE 0x04
#define COLOUR_CYAN (COLOUR_BLUE | COLOUR_GREEN) // 0x06
// Encoding
SetColour(COLOUR_RED | COLOUR_BLUE); // Parameter is 0x05
// Decoding
void SetColour(int colour)
{
if (colour & COLOUR_RED) // If the mask contains COLOUR_RED
// Do whatever
if (colour & COLOUR_BLUE) // If the mask contains COLOUR_BLUE
// Do whatever
// ..
}
What they are doing there is using binary OR to combine the flags together.
so what is actually happening is:
0x10003003 | 0x10003004 | 0x10003005 == 0x10003007
It's still one parameter, but the 3 flags will combine to create a unique value for that parameter which can be used in the function.
What you are defining as multiple parameter is strictly a single parameter from the function signature point of view.
As for handling multiple Options based on a single parameter, as you can see there is the bitwise Or Operator which sets a single value for the parameter value. The body of the function then uses individual bits to determine the complete settings.
Usually, one bit is allocated for one option and they usually have two state(true/false) values.
The parameter is usually called "flags" and contains an or-ed combination of a set of allowed values.
int flags = API_FULLSCREEN | API_NO_DELAY;
The function can the take this integer parameter and extract the individual items like this:
int fullscreen_set = flags & API_FULLSCREEN;
int no_delay_set = flags & API_NO_DELAY;
int blah_blah_set = flags & API_BLAH_BLAH;
For this to work one has to be carfull in how one chooses the numeric values for the API_* parameters.
Bitwise OR
Bitwise OR works almost exactly the same way as bitwise AND. The only difference is that only one of the two bits needs to be a 1 for that position's bit in the result to be 1. (If both bits are a 1, the result will also have a 1 in that position.) The symbol is a pipe: |. Again, this is similar to boolean logical operator, which is ||.
01001000 | 10111000 = 11111000
and consequently
72 | 184 = 248
So In you Method not a multiple parameter it is actully one parameter.
you can use Bitwise OR opearation on API_FULLSCREEN | API_NO_DELAY | API_BLAH_BLAH and passed it in method.
The example that you gave will not work as expected. What you do is to use a particular bit for a particular option - and the OR combines then
Example
#define OPT1 1
#define OPT2 2
#define OPT3 4
So bit 1 is for OPT1, bit 2 is for OPT2 etc.
So OPT1 | OPT3 sets bit 1 and 3 and gives a value of 5
In the function you can test if a particular option is required using the AND operator
So
void perform(int opts)
{
if (opts & OPT1)
{
// Do stuff for OPT1
}
...
The value of these parameters are defined in a way that they don't have any overlap. Something like this:
#define A 0x01
#define B 0x02
#define C 0x04
#define D 0x08
Given the above definitions, your can always determine which of the above variables have been ORed using the bitwise AND operator:
void foo(int param)
{
if(param & A)
{
// then you know that A has been included in the param
}
if(param & B)
{
// then you know that B has been included in the param
}
...
}
int main()
{
foo (A | C);
return 0;
}
I am new to C++ and have programming knowledge only in Java. Can anyone please explain the meaning of the code below:
#define DEF 134 ;
int k;
char msk;
PMSK *pm; //At the begining of class some declaration
// i is some counter(int)
if ( (nVersion >= 2004) && (nVersion < 2008))
{
k = to_bits(DEF, &msk);
if ( pm->orbits[k] & msk ) // for version >= 2004
{
x = atoi( grprs[i] );
if ( !defpair( i, x ) )
pm->orbits[k] &= 0xFF ^ msk; // turn off bit
}
}
to_bits() is method which will return an integer value and a (char) msk value (example 1000). It has bit operations involved in it.
What is pm->orbits[k]? Can we replace it in Java like pm.orbits[k]?
Also, what exactly the last line of code doing?
What is pm->orbits[k]? can we replace it in java like pm.orbits[k]?
Basically, yes. The -> operator de-references and then access a field (also known as access the field/function of the object pointed to by the pointer). However, if you had a reference type to begin with, you get the de-referencing "for free".
PMSK *pm1; // assume this has been initialized to point to something valid
PMSK &pm2; // assume this is a valid reference
PMSK pm3; // assume this is a valid declaration
pm1->orbits[0]; // accesses field orbits[0] of object pointed to by pm1
(*pm1).orbits[0]; // equivalent to above statement
pm2.orbits[0]; // it's implicitly understood that de-referencing should take place
pm3.orbits[0]; // no need to dereference
Dissecting the last line of code:
pm->orbits[k] &= 0xFF ^ msk; // turn off bit
^ is the bitwise exclusive or operator (a.k.a. xor). Basically it returns a bit value of 1 if both bits are not equal and 0 otherwise.
&= is the bitwise-and assigment operator. Equivalent to the following:
pm->orbits[k] = pm->orbits[k] & (0xFF^msk);
The bitwise and operator matches up equivalent bits and determines if both are 1. If they are, the result is 1. Otherwise, it's 0. So 100001 & 100100 = 100000 (binary numbers).
So it takes whatever's in msk, toggles the lowest 8 bits (1 -> 0 and 0 -> 1), then bitwise-ands that with the current pm->orbits[k] field. Finally, it assigns the result back to pm->orbits[k]
In Java, it's required to have an explicit check to somehow convert the results from a number to a boolean. However, in C++ it's implicitly understood that anything which isn't 0 is true.
if(1) // same as if(1!=0)
if(2) // same as if(2!=0)
if(0) // same as if(0!=0)
if(-1) // same as if(-1!=0)
Yes you can replace the code you mention. The '->' operator dereferences a pointer to a PMSK object. Java doesn't have pointers, only references, but they are used in the same way.
The last line is clearing the bits set in msk, however it's normally done like this:
pm->orbits[k] &= ~msk;
If you want to set the bits in msk, you'd use:
pm->orbits[k] |= msk;
Also, the following line will need to evaluate to a boolean expression, where as in C++ it just needs to be non-zero:
if ((pm->orbits[k] & msk) != 0)
{
...
}
What is pm->orbits[k]? can we replace
it in java like pm.orbits[k]?
Yes, pm is a pointer, and the -> notation is how to access members on a pointer.
The last line is a bitwise operation, called an exclusive or, the ^ operator is the same and does the same thing in Java.
The -> operator dereferences a pointer to select a field.
The last line of code does a bitwise exclusive or (XOR) of the msk value with 0xFF. This value is then bitwise ANDed with the pm->orbits array value at index k.
A few subjects that are going to help as you learn C++ and work with this code
Pointers in general
http://www.cplusplus.com/doc/tutorial/pointers/
C++ for Java Programmers ht
Bitwise operations in general http://vipan.com/htdocs/bitwisehelp.html
Arrays in C++
Passing by reference and value
Just about any introductory C++ text will have this info.
& has &&. | has ||. Why doesn't ^ have ^^?
I understand that it wouldn't be short-circuiting, but it would have different semantics. In C, true is really any non-zero value. Bitwise XOR is not always the same thing as logical XOR:
int a=strcmp(str1,str2);// evaluates to 1, which is "true"
int b=strcmp(str1,str3);// evaluates to 2, which is also "true"
int c=a ^^ b; // this would be false, since true ^ true = false
int d=a ^ b; //oops, this is true again, it is 3 (^ is bitwise)
Since you can't always rely on a true value being 1 or -1, wouldn't a ^^ operator be very helpful? I often have to do strange things like this:
if(!!a ^ !!b) // looks strange
Dennis Ritchie answers
There are both historical and practical reasons why there is no ^^ operator.
The practical is: there's not much use for the operator. The main point of && and || is to take advantage of their short-circuit evaluation not only for efficiency reasons, but more often for expressiveness and correctness.
[...]
By contrast, an ^^ operator would always force evaluation of both arms of the expression, so there's no efficiency gain. Furthermore, situations in which ^^ is really called for are pretty rare, though examples can be created. These situations get rarer and stranger as you stack up the operator--
if (cond1() ^^ cond2() ^^ cond3() ^^ ...) ...
does the consequent exactly when an odd number of the condx()s are true. By contrast, the && and || analogs remain fairly plausible and useful.
Technically, one already exists:
a != b
since this will evaluate to true if the truth value of the operands differ.
Edit:
Volte's comment:
(!a) != (!b)
is correct because my answer above does not work for int types. I will delete mine if he adds his answer.
Edit again:
Maybe I'm forgetting something from C++, but the more I think about this, the more I wonder why you would ever write if (1 ^ 2) in the first place. The purpose for ^ is to exclusive-or two numbers together (which evaluates to another number), not convert them to boolean values and compare their truth values.
This seems like it would be an odd assumption for a language designer to make.
For non-bool operands, I guess what you would want is for a ^^ b to be evaluated as:
(a != 0) ^ (b != 0)
Well, you have the above option and you have a few options listed in other answers.
The operator ^^ would be redundant for bool operands. Talking only about boolean operands, for the sake of argument, let's pretend that ^ was bitwise-only and that ^^ existed as a logical XOR. You then have these choices:
& - Bitwise AND -- always evaluates both operands
&& - Logical AND -- does not always evaluate both operands
| - Bitwise OR -- always evaluates both operands
|| - Logical OR -- does not always evaluate both operands
^ - Bitwise XOR -- must always evaluate both operands
^^ - Logical XOR -- must always evaluate both operands
Why didn't they create ^^ to essentially convert numerical values into bools and then act as ^? That's a good question. Perhaps because it's more potentially confusing than && and ||, perhaps because you can easily construct the equivalent of ^^ with other operators.
I can't say what was in the heads of Kernighan and Ritchie when they invented C, but you made a brief reference to "wouldn't be short-circuiting", and I'm guessing that's the reason: It's not possible to implement it consistently. You can't short-circuit XOR like you can AND and OR, so ^^ could not fully parallel && and ||. So the authors might well have decided that making an operation that sort of kind of looks like its parallel to the others but isn't quite would be worse than not having it at all.
Personally, the main reason I use && and || is for the short-circuit rather than the non-bitwise. Actually I very rarely use the bitwise operators at all.
Another workaround to the ones posted above (even if it requires another branch in the code) would be:
if ( (a? !b : b ) )
that is equivalent to xor.
In Java the ^ operator indeed does do logical XOR when used on two boolean operands (just like & and | in Java do non-short-circuiting logical AND and OR, respectively, when applied to booleans). The main difference with C / C++ is that C / C++ allows you to mix integers and booleans, whereas Java doesn't.
But I think it's bad practice to use integers as booleans anyway. If you want to do logical operations, you should stick to either bool values, or integers that are either 0 or 1. Then ^ works fine as logical XOR.
An analogous question would be to ask, how would you do non-short-circuiting logical AND and OR in C / C++? The usual answer is to use the & and | operators respectively. But again, this depends on the values being bool or either 0 or 1. If you allow any integer values, then this does not work either.
Regardless of the case for or against ^^ as an operator, you example with strcmp() sucks. It does not return a truth value (true or false), it returns a relation between its inputs, encoded as an integer.
Sure, any integer can be interpreted as a truth value in C, in which case 0 is "false" and all other values are "true", but that is the opposite of what strcmp() returns.
Your example should begin:
int a = strcmp(str1, str2) == 0; // evaluates to 0, which is "false"
int b = strcmp(str1, str3) == 0; // evaluates to 0, which is also "false"
You must compare the return value with 0 to convert it to a proper boolean value indicating if the strings were equal or not.
With "proper" booleans, represented canonically as 0 or 1, the bitwise ^ operator works a lot better, too ...