My C++ code is as follows:
#include <iostream>
using namespace std;
int main() {
int i = 0;
cout << (i=0) << endl;
if(i=0) {
i=1;
}
cout << i;
return 0;
}
Why is (i=0) equal to 0?
You have confused the assignment operator '=' with the equality operator '=='.
Thus, your if statement if(i=0) isn't checking whether i is equal to 0, it is assigning 0 to i. And since that assignment succeeded, the if succeeded and so i was subsequently assigned to the value in the statement.
EDIT:
As per request: Why does "cout<<(i=0);" put out"0"?
cout<<(i=0)<<endl; prints zero because once again, i=0 is an assignment statement, not a comparison statement. It is not comparing i to 0 then printing the result, it is assigning i to 0 and then printing i. Since i is 0, the character '0' gets printed.
If you put you condition to if(condition) statements:
If value returned by condition is != 0, then statements are executed
If value returned by condition is == 0 then statements are not executed.
Assignment operator return the reference to value
So:
If you put assignment operator to if, then the results of the assignment will be checked and i=0 return 0 so the statements won't be executed.
If you put your code on more lines and use a debugger you can answer your own question.
Should be obvious that the body of if(0) never runs.
Related
I have defined a constexpr function as following:
constexpr int foo(int i)
{
return i*2;
}
And this is what in the main function:
int main()
{
int i = 2;
cout << foo(i) << endl;
int arr[foo(i)];
for (int j = 0; j < foo(i); j++)
arr[j] = j;
for (int j = 0; j < foo(i); j++)
cout << arr[j] << " ";
cout << endl;
return 0;
}
The program was compiled under OS X 10.8 with command clang++. I was surprised that the compiler did not produce any error message about foo(i) not being a constant expression, and the compiled program actually worked fine. Why?
The definition of constexpr functions in C++ is such that the function is guaranteed to be able to produce a constant expression when called such that only constant expressions are used in the evaluation. Whether the evaluation happens during compile-time or at run-time if the result isn't use in a constexpr isn't specified, though (see also this answer). When passing non-constant expressions to a constexpr you may not get a constant expression.
Your above code should, however, not compile because i is not a constant expression which is clearly used by foo() to produce a result and it is then used as an array dimension. It seems clang implements C-style variable length arrays as it produces the following warning for me:
warning: variable length arrays are a C99 feature [-Wvla-extension]
A better test to see if something is, indeed, a constant expression is to use it to initialize the value of a constexpr, e.g.:
constexpr int j = foo(i);
I used the code at the top (with "using namespace std;" added in) and had no errors when compiling using "g++ -std=c++11 code.cc" (see below for a references that qualifies this code) Here is the code and output:
#include <iostream>
using namespace std;
constexpr int foo(int i)
{
return i*2;
}
int main()
{
int i = 2;
cout << foo(i) << endl;
int arr[foo(i)];
for (int j = 0; j < foo(i); j++)
arr[j] = j;
for (int j = 0; j < foo(i); j++)
cout << arr[j] << " ";
cout << endl;
return 0;
}
output:
4
0 1 2 3
Now consider reference https://msdn.microsoft.com/en-us/library/dn956974.aspx It states: "...A constexpr function is one whose return value can be computed at compile when consuming code requires it. A constexpr function must accept and return only literal types. When its arguments are constexpr values, and consuming code requires the return value at compile time, for example to initialize a constexpr variable or provide a non-type template argument, it produces a compile-time constant. When called with non-constexpr arguments, or when its value is not required at compile-time, it produces a value at run time like a regular function. (This dual behavior saves you from having to write constexpr and non-constexpr versions of the same function.)"
It gives as valid example:
constexpr float exp(float x, int n)
{
return n == 0 ? 1 :
n % 2 == 0 ? exp(x * x, n / 2) :
exp(x * x, (n - 1) / 2) * x;
}
This is an old question, but it's the first result on a google search for the VS error message "constexpr function return is non-constant". And while it doesn't help my situation, I thought I'd put my two cents in...
While Dietmar gives a good explanation of constexpr, and although the error should be caught straight away (as it is with the -pedantic flag) - this code looks like its suffering from some compiler optimization.
The value i is being set to 2, and for the duration of the program i never changes. The compiler probably noticed this and optimized the variable to be a constant (just replacing all references to variable i to the constant 2... before applying that parameter to the function), thus creating a constexpr call to foo().
I bet if you looked at the disassembly you'd see that calls to foo(i) were replaced with the constant value 4 - since that is the only possible return value for a call to this function during execution of the program.
Using the -pedantic flag forces the compiler to analyze the program from the strictest point of view (probably done before any optimizations) and thus catches the error.
Can we make use of function in for loop in c programming language like the below example...
#include <stdio.h>
int main()
{
int i = 0;
for (foo(); i == 1; i = 2)
printf("In for loop\n");
printf("After loop\n");
}
int foo()
{
return 1;
}
Also please explain the output of this code ....Answer --->After loop.
yes you can, so it will return 1 and the loop will never be executed. the loop will be executed if i==1 but i is still 0. This will mean the statement printf("In for loop\n"); is not executed and it will continue after this loop -> printf("After loop\n");
for better understanding you could use brackets surrounding the for loop and indentation.without brackets the for loop includes just the next statement:
for (foo(); i == 1; i = 2){
printf("In for loop\n");
}
printf("After loop\n");
The way you are using for loops does not make a whole lot of sense.
The place where you are calling foo() is where the loop variable usually gets initialized.
Think about the general concepts of for loops:
for (INITIALIZATION; CONDITION; AFTERTHOUGHT)
It would make more sense to write
for (i = foo(); i == 1; i = 2)
I see another problem with your for loop in the AFTERTHOUGHT part.
You usually want to modify the loop variable there, but in a way that it depends on the previous state. In the most simple case just increment it, thus write:
for (i = foo(); i == 1; i++)
Then look at the CONDITION part. It should be true for a range of values, otherwise the loop will terminate quickly (after one iteration in this case). You would maybe want to write something like
for (i = foo(); i <= 3; i++)
to have 3 iterations.
You get the basic idea?
The C++11 range-based for loop dereferences the iterator. Does that mean that it makes no sense to use it with boost::adaptors::indexed? Example:
boost::counting_range numbers(10,20);
for(auto i : numbers | indexed(0)) {
cout << "number = " i
/* << " | index = " << i.index() */ // i is an integer!
<< "\n";
}
I can always use a counter but I like indexed iterators.
Is it possible to use them somehow with range-based for loops?
What is the idiom for using range-based loops with an index? (just a plain counter?)
This was fixed in Boost 1.56 (released August 2014); the element is indirected behind a value_type with index() and value() member functions.
Example: http://coliru.stacked-crooked.com/a/e95bdff0a9d371ea
auto numbers = boost::counting_range(10, 20);
for (auto i : numbers | boost::adaptors::indexed())
std::cout << "number = " << i.value()
<< " | index = " << i.index() << "\n";
It seems more useful when iterating over collection, where you may need the index position (to print the item number if not for anything else):
#include <boost/range/adaptors.hpp>
std::vector<std::string> list = {"boost", "adaptors", "are", "great"};
for (auto v: list | boost::adaptors::indexed(0)) {
printf("%ld: %s\n", v.index(), v.value().c_str());
}
Prints:
0: boost
1: adaptors
2: are
3: great
Any innovation for simply iterating over integer range is strongly challenged by the classic for loop, still very strong competitor:
for (int a = 10; a < 20; a++)
While this can be twisted up in a number of ways, it is not so easy to propose something that is obviously much more readable.
The short answer (as everyone in the comments mentioned) is "right, it makes no sense." I have also found this annoying. Depending your programming style, you might like the "zipfor" package I wrote (just a header): from github
It allows syntax like
std::vector v;
zipfor(x,i eachin v, icounter) {
// use x as deferenced element of x
// and i as index
}
Unfortunately, I cannot figure a way to use the ranged-based for syntax and have to resort to the "zipfor" macro :(
The header was originally designed for things like
std::vector v,w;
zipfor(x,y eachin v,w) {
// x is element of v
// y is element of w (both iterated in parallel)
}
and
std::map m;
mapfor(k,v eachin m)
// k is key and v is value of pair in m
My tests on g++4.8 with full optimizations shows that the resulting code is no slower than writing it by hand.
Consider we have a sequence of numbers arriving in sequential order (N numbers in total). How to develop a one-pass (that is, during the sequence arrival) O(N) algorithm to find the number (and it's position in the sequence) of minimal nonzero magnitude? Note that standard simple algorithm doesn't work here, since the initial number could be zero.
One way to solve this would be to model it as a sort of state machine with two states. In the initial state, you have not seen any nonzero values yet, and so the answer is "there is no number meeting this criterion." In this state, any time you see a zero you remain in the state. On a nonzero value, record that value and go to the next state. This next state means "I have seen at least one nonzero value, and now I need to keep track of the smallest value I've seen." Once you get here, whenever you get a nonzero value as input to the algorithm, you compare its magnitude to the magnitude of the value with the smallest nonzero magnitude that you've seen, then keep the smaller of the two.
A simple implementation of this in a C-like language might look like this:
bool seenNonzeroValue = false;
double minValue; /* No initializer necessary; we haven't seen anything. */
while (MoreDataExists()) {
double val = GetNextElement();
/* If the value is zero, we ignore it. */
if (val == 0.0) continue;
/* If the value is nonzero, then the logic depends on our state. */
*
* If we have not seen any values yet, then record this value as the first
* value we've seen.
*/
if (!seenNonzeroValue) {
seenNonzeroValue = true;
minValue = val;
}
/* Otherwise, keep the number with the smaller magnitude. */
else {
if (fabs(val) < fabs(minValue))
minValue = val;
}
}
/* If we saw at least one value, report it. Otherwise report an error. */
if (seenNonzeroValue)
return minValue;
else
ReportError("No nonzero value found!");
Hope this helps!
You don't need to track whether you've seen non-zero value or not. You could use sentinel values instead. Adapting the code from the #templatetypedef' answer:
size_t pos = 0, minpos = -1; // track position as per the question requirements
double minValue = POSITIVE_INFINITY; // e.g., `1/+0.`
for ( ; MoreDataExists(); ++pos) {
double val = GetNextElement();
if (val and fabs(val) <= fabs(minValue)) { // skip +0, -0; update minValue
minpos = pos;
minValue = val;
}
}
if (minpos != -1)
// found non-zero value with a minimal magnitude
return make_pair(minpos, minValue);
else if (pos == 0)
ReportError("sequence is empty");
else
ReportError("no nonzero value found");
Example in C++
#include <algorithm>
#include <cmath>
#include <iostream>
#include <limits>
typedef double val_t;
typedef double* it_t;
int main () {
val_t arr[] = {0, 0, 1, 0, 0, 2, 0}; // input may be any InputIterator
it_t pend = arr + sizeof(arr)/sizeof(*arr);
val_t sentinel = std::numeric_limits<val_t>::infinity();
it_t pmin = &sentinel;
for (it_t first = arr; first != pend; ++first)
// skip +0,-0; use `<=` to allow positive infinity among values
if (*first and std::abs(*first) <= std::abs(*pmin))
pmin = first;
if (pmin != &sentinel)
std::cout << "value: " << *pmin << '\t'
<< "index: " << (pmin - arr) << std::endl;
else
std::cout << "not found" << std::endl;
}
Output
value: 1 index: 2
You need to consider the possible cases involved in processing each number in the sequence, ie: is it zero or non-zero and if non-zero is it the first non-zero one or not? Then have the alogrithm deal with each case. I'd recommend using a logical flag to track the latter case.
Consider you have some expression like
i = j = 0
supposing this is well-defined in your language of choice. Would it generally be better to split this up into two expressions like
i = 0
j = 0
I see this sometimes in library code. It doesn't seem buy you much in terms of brevity and shouldn't perform any better than the two statements (though that may be compiler dependant). So, is there a reason to use one over the other? Or is it just personal preference? I know this sounds like a silly question but it's bugging me for a long time now :-).
Once upon a time there was a performance difference, which is one of the reason that this kind of assignment was used. The compilers would turn i = 0; j = 0; into:
load 0
store [i]
load 0
store [j]
So you could save an instruction by using i = j = 0 as the compiler would turn this into:
load 0
store [j]
store [i]
Nowadays compilers can do this type of optimisations by themselves. Also, as the current CPUs run several instructions at once, performance can no longer simply be measured in number of instructions. Instructions where one action doesn't rely on the result of another can run in parallel, so the version that uses a separate value for each variable might actually be faster.
Regarding programming style, you should use the way that best expresses the intention of the code.
You can for example chain the assignments when you simply want to clear some variables, and make it separate assignments when the value has a specific meaning. Especially if the meaning of setting one variable to the value is different from setting the other variable to the same value.
The two forms reflects different points of view on the assignment.
The first case treats assignment (at least the inner one) as an operator (a function returning a value).
The second case treats assignment as a statement (a command to do something).
There is some cases where the assignment as an operator has it's point, mostly for brevity, or to use in contexts that expect a result. However I feel it confusing. For several reasons:
Assignment operator are basically side effect operators, and nowadays it's a problem to optimize them for compilers. In languages like C and C++ they lead to many Undefined Behavior cases, or unoptimized code.
It is unclear what it should return. Should assignment operator return the value that as been assigned, or should it return the address of the place it has been stored. One or the other could be useful, depending on the context.
With composite assignments like +=, it's even worse. It is unclear if the operator should return the initial value, the combined result, or even the place it was stored to.
The assignment as a statement lead sometimes to intermediate variables, but that's the only drawback I see. It is clear and compilers know how to optimize efficiently successive such statements.
Basically, I would avoid assignment as operator whenever possible. The presented case is very simple and not really confusing, but as a general rule I would still prefer.
i = 0
j = 0
or
i, j = 0, 0
for languages that supports, parallel assignment.
It depends on the language. In highly-object-oriented languages, double assignment results in the same object being assigned to multiple variables, so changes in one variable are reflected in the other.
$ python -c 'a = b = [] ; a.append(1) ; print b'
[1]
Firstly, at a semantic level, it depends whether you want to say that i and j are the same value, or just happen to both have the same value.
For example, if i and j are the indexes into a 2D array, they both start at zero. j = i = 0 says i starts at zero, and j starts where i started. If you wanted to start at the second row, you wouldn't necessarily want to start at the second column, so I wouldn't initialise them both in the same statement - the indices for rows and columns independently happen to both start at zero.
Also, in languages where i and j represent complicated objects rather than integral variables, or where assignment may cause an implicit conversion, they are not equivalent:
#include <iostream>
class ComplicatedObject
{
public:
const ComplicatedObject& operator= ( const ComplicatedObject& other ) {
std::cout << " ComplicatedObject::operator= ( const ComplicatedObject& )\n";
return *this;
}
const ComplicatedObject& operator= ( int value ) {
std::cout << " ComplicatedObject::operator= ( int )\n";
return *this;
}
};
int main ()
{
{
// the functions called are not the same
ComplicatedObject i;
ComplicatedObject j;
std::cout << "j = i = 0:\n";
j = i = 0;
std::cout << "i = 0; j = 0:\n";
i = 0;
j = 0;
}
{
// the result of the first assignment is
// effected by implicit conversion
double j;
int i;
std::cout << "j = i = 0.1:\n";
j = i = 0.1;
std::cout << " i == " << i << '\n'
<< " j == " << j << '\n'
;
std::cout << "i = 0.1; j = 0.1:\n";
i = 0.1;
j = 0.1;
std::cout << " i == " << i << '\n'
<< " j == " << j << '\n'
;
}
}
Most of the people will find both possibilities equally readable. Some of these people will have a personal preference for either way. But there are people who might, at first glance, get confused by the "double assignment". I personally like the separate approach, bacause
It is 100% readable
It is not really verbose compared to the double variant
It allows me forget the rules of associativity for = operator
The second way is more readable and clear, I prefer it.
However I try to avoid "double" declaration:
int i, j;
instead of
int i;
int j;
if they're going consecutively. Especially in case of MyVeryLong.AndComplexType