This question already has answers here:
Does C++ support compile-time counters?
(11 answers)
Closed 8 years ago.
I know this is a weird question, but I'm trying to find a way to analyze the code written by the user and collect some useful information that may be included in both "if" & "else" part.
Suppose I have an if-else statement,
counter = 0;
if( true )
++counter;
else
++counter;
is it possible that I can "enforce ++counter" to work and get "counter = 2" at compiler time? Template? Macro? Any other solution? Thanks in advance!
First of all, `counter' will never be 2. It will always be 1.
I'd say about 90% of current C++ compilers (running in "Release" mode") will recognize the invariant, and generate object code as if you had written:
counter = 0;
++counter;
Most will also go as far as
counter = 1;
However, such optimizations are not required by the Standard, so there is no way to "Force" a compiler to do them.
NOTE: The specifications for Java & C# do require compilers for those languages to recognize the invariant to do elide the if())
Related
This question already has an answer here:
Loop unrolling behaviour in GCC
(1 answer)
Closed 4 years ago.
I am trying to generate multiple programs from a given C/C++ program with loops unrolled. For example, I would like to convert something like this:
i = 0;
while (i < 5) {
printf("Hello");
i++;
}
to this:
i = 0;
printf("Hello");
i++;
while (i < 5) {
printf("Hello");
i++;
}
In the above example, I'd like to generate 5 programs each with a different number of loops unrolled. The compiler flags that I have looked at so far don't seem to generate a program but just optimize it. Is there any straightforward automated way of doing this?
Edit: I don't understand why this is being downvoted. The question linked as being a duplicate isn't relevant.
Is there any straightforward automated way of doing this?
This is an unusual requirement, as such I think you will have a really difficult time to find a tool that does this.
Without knowing what you are trying to achieve, what problem you are trying to resolve we can't give you a solution, other than manual unroll:
printf("Hello");
printf("Hello");
printf("Hello");
printf("Hello");
printf("Hello");
If the programs you want to change are all written by yourself and you know they're structure is simple, you may get along witha little magic of regular expressions.
For modifying arbitrary programs reliably, you must use a proper parser, detect constant for loops in the abstract syntax tree and then write back the modified syntax tree.
This question already has answers here:
Multiple preincrement operations on a variable in C++(C ?)
(2 answers)
Closed 6 years ago.
I have some code with lines which increment a counter.
++ count;
Sometimes I have an if condition which means I should increment count by 2.
count += 2;
Does "double increment'ing" work in the same way?
++ ++ count;
It would be helpful to know if both C and C++ compilers interpret this the same way.
As this is clearly syntactically correct, the question that remains is: "Is this UB because of unsequenced writes?"
It is not (in C++11 and later) because
5) The side effect of the built-in pre-increment and pre-decrement operators is sequenced before its value computation (implicit rule due to definition as compound assignment)
(From here)
So the code is fine as of C++11.
However, the sequencing rules were different before that, and pre-C++11, the code actually has UB.
In C, that code does not even compile.
The fact that the behavior is different between C and C++ and even between different C++ standards and that this question arises in the first place is a hint that the simple count += 2; is the safer and more readable version. You should prefer it over the "cute and clever" ++ ++count;.
There are two methods. One that obviously works, one where you have to ask a question on StackOverflow. There are comments saying "in C++ 11 or later"... How sure are you that your C++ code runs with C++ 11 and not something older? Even if you use extensions that were not part of an earlier language, your language could be C++0x with some extensions.
Clearly you shouldn't care whether the second method works or not, but use the one that obviously works.
This question already has answers here:
What is the difference between if(CONST==variable) or if(variable==CONST)?
(5 answers)
Closed 9 years ago.
I've come across some code that flips how a condition is checked and was wondering why this would be done aside from a weird personal quirk. I've never seen any text books use it nor have I seen any sample code done this way.
// why do it this way?
if (5 == myValue)
{
// do something
}
// instead of:
if (myValue == 5)
{
// do something
}
I've only seen this way for == operand but not for any other operands.
Some people like doing that because if you mess up and type a single-equals instead of a double-equals, "if (val = 5)" is only a compiler warning, while "if (5 = val)" is an error (you can't assign to a constant).
I think it's sort of ugly, personally, and that you should be checking your warnings just as much as your errors, but that is the reason for that convention (which is thankfully not universal, but is at least moderately widespread. It is also true that it might not universally have been treated as even a warning by much older compilers, and this convention has been around for a long time.)
Fun fact: I was just reading Code Complete (Second Edition), and Steve McConnell agrees with me, stating his personal preference is "to use number-line ordering and let the compiler warn me about unintended assignments". Steve McConnell by definition knows what he's talking about.
Some folks do it for readability when myValue is deemed less interesting than 5; it puts the constant value in a more prominent place. There is no practical reason for it - purely a judgment call on the part of the coder.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I think the following code is evil, but it can be compiled without any warning.
int f(int n)
{
return n + 1;
}
int n = 0;
n = f(n++) + f(++n);
I just wonder why the Holy Standard doesn't deprecate such operators?
I guess there might be two reasons:
One might be for backward compatibility;
Another might be for that under some cases these operators are very useful.
If the latter is true, could you give me some examples? Thanks.
It's more than evil, it's Undefined Behaviour™. Which is why all sane people ban such uses.
Backwards compatibility is surely half the problem- increment and decrement are used everywhere. They're also useful for iterators and stuff.
The bottom line is, C++ has never, ever stopped you from shooting yourself in the foot. This is just one example. C++ does not ban things that can be good just because they can be bad. Not abusing them is your problem.
To remove these ++ and -- operators from C and/or C++ would certainly break A LOT of code - in fact I suspect, if you remove those two operators, just about every single existing source file will stop compiling.
They are very useful when used correctly - as long as you don't use it on both sides of the same variable, you'll be fine.
This code won't compile, but adding parenthesis to make it (++n)++ does compile correctly - but g++ gives a warning "operation on ‘n’ may be undefined".
And if we remove the ++ and -- operator, how do you expect to write a common for-lopp:
for(int i = 0; i < 100; i++)
like this:
for(int i = 0; i < 100; i = i + 1)
or
for(int i = 0; i < 100; i += 1)
Banning everything that can be misused in C and C++ would pretty much reduce the language to nothing - and certainly either make the language completely useless or at least prevent a lot of valid uses. It'd be like banning knifes, because people CAN use them (and indeed have used them) for bad things. But if you want to cut bread, meat or vegetables, they do make darn handy tools for that purpose.
I just wonder why the Holy Standard doesn't deprecate such operators?
Because this is perfectly valid code, but it invokes unspecified behavior, since the order of evaluation of operands in a C expression isn't specified. The only problem in the code was created by the programmer, who has written code that relies on unspecified behavior. It is not the C standard's task to educate programmers about the language.
(This is not undefined behavior. See C11 6.5.2.2. There is a sequence point between the evaluations of the function designator and actual arguments in a function call and the actual call. Had it not been for the sequence point after each function parameter evaluation, it would have been undefined behavior, because you can't modify the same variable twice in an operation without a sequence point in between.)
One might be for backward compatibility;
No. C has always had unspecified order of evaluation of operands. This code works the same from pre-standard K&R code all the way to C11.
Another might be for that under some cases these operators are very useful.
No, the code you posted is not useful in any kind of scenario. It is obfuscated and can be written in better ways to achieve the very same functionality and identical machine code, in a safer, more readable way. For example:
n++;
n = f(n) + f(n);
n++;
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is “for(;;)” faster than “while (TRUE)”? If not, why do people use it?
Found code with this for-loop.
What exactly feature to use it insted of while(true) for example? Is it uses less memory ?
for(;;) is functionally equivalent to while(true) but avoids a "conditional expression is constant" warning with some compilers (including MSVC's cl)
This construct has been popularized by Kernighan and Ritchie in their C Programming Language book (section 3.5)
The for statement
for (expr1; expr2; expr3)
statement
If expr1 or expr3 is omitted, it is simply dropped from the expansion. If the test, expr2, is not present, it is taken as permanently true, so
for (;;) {
...
}
is an "infinite" loop, presumably to be broken by other means, such as a break or return.
There is absolutely no difference between for(;;) and while(true).
while(true)
{
}
Is always what I've used and what I've seen others use for a loop that has to be broken manually.
Some compilers are giving you wrnings that this while loom MAY be incorrect. But it is not.
The assembly code generated for both is exactly the same. No diferences.
First, The use of loop depends on the requirement & based on that only we can decide when to use which one. Just check what #Luchian has asked, then you will come to know it.
Secondly, that clearly depends on the particular implementation of the interpreter/compiler of the specific language.
That said, theoretically, any sane implementation is likely to be able to implement one in terms of the other if it was faster so the difference should be negligible at most.