I'm getting a warning in my constructor in my class, and I've never seen it before. This is what my constructor looks like.
Account(std::string n = "NULL", std::string i = "0", Stats s = (0,0,1) )
: name(n), id(i), stat(s) {}
If I remove any of these commas it results in a compile error, no?
Is this warning incorrect, or is there something I can change to fix it?
The issue is this: (0,0,1).
That is parentheses around the expression 0,0,1, which evaluates to 1. (The comma operator is an infix operator that evaluates the first and second expression and returns the second. In this case, you have two such operators.)
I don't know what you wanted there, but I'm guessing that isn't it.
EDIT: It seems you want Stats s(0,0,1).
The problem is most likely in that part Stats s = (0,0,1). C++ sees this as a sequence of expression to be computed while keeping only the last value. It returns 1. You probably mean
Stats s = Stats(0,0,1)
which works if your stats structure have such a constructor. Note that in C++11 you have this shorter syntax:
Stats s = {0,0,1}
I think what you are looking for is to give a default value to function argument which is a struct, and I think it was discussed here How can I assign a default value to a structure in a C++ function?
Related
Hi I am new here and want to solve this problem:
do k=1,31
Data H(1,k)/0/
End do
do l=1,21
Data H(l,1)/0.5*(l-1)/
End do
do m=31,41
Data H(17,m)/0/
End do
do n=17,21
Data H(n,41)/0.5*(n-17)/
End do
I get error for l and n saying that it is a syntax error in DATA statement. Anyone know how to solve this problem?
You have three problems here, and not just with the "l" and "n" loops.
The first problem is that the values in a data statement cannot be arbitrary expressions. In particular, they must be constants; 0.5*(l-1) is not a constant.
The second problem is that the bounds in the object lists must also be constant (expressions); l is not a constant expression.
For the first, it's also worth noting that * in a data value list has a special meaning, and it isn't the multiplication operator. * gives a repeat count, and a repeat count of 0.5 is not valid.
You can fix the second point quite simply, by using such constructions as
data H(1,1:31) /31*0./ ! Note the repeat count specifier
outside a loop, or using an implied loop
data (H(1,k),k=1,31) /31*0./
To do something for the "l" loop is more tedious
data H(1:21,1) /0., 0.5, 1., 1.5, ... /
and we have to be very careful about the number of values specified. This cannot be dynamic.
The third problem is that you cannot specify explicit initialization for an element more than once. Look at your first two loops: if this worked you'd be initializing H(1,1) twice. Even though the same value is given, this is still invalid.
Well, actually you have four problems. The fourth is related to the point about dynamic number of values. You probably don't want to be doing explicit initialization. Whilst it's possible to do what it looks like you want to do, just use assignment where these restrictions don't apply.
do l=1,21
H(l,1) = 0.5*(l-1)
End do
Yes, there are times when complicated explicit initialization is a desirable thing, but in this case, in what I assume is new code, keeping things simple is good. An "initialization" portion of your code which does the assignments is far more "modern".
I was writing some C++ code and mistakenly omitted the name of a function WSASocket. However, my compiler did not raise an error and associated my SOCKET with the integer value 1 instead of a valid socket.
The code in question should have looked like this:
this->listener = WSASocket(address->ai_family, address->ai_socktype, address->ai_protocol, NULL, NULL, WSA_FLAG_OVERLAPPED);
But instead, it looked like this:
this->listener = (address->ai_family, address->ai_socktype, address->ai_protocol, NULL, NULL, WSA_FLAG_OVERLAPPED);
Coming from other languages, this looks like it may be some kind of anonymous type. What is the name of the feature, in the case it is really a feature?
What is its purpose?
It's difficult to search for it, when you don't know where to begin.
The comma operator† evaluates the left hand side, discards its value, and as a result yields the right hand side. WSA_FLAG_OVERLAPPED is 1, and that is the result of the expression; all the other values are discarded. No socket is ever created.
† Unless overloaded. Yes, it can be overloaded. No, you should not overload it. Step away from the keyboard, right now!
The comma operator is making sense of your code.
You are effectively setting this->listener = WSA_FLAG_OVERLAPPED; which just happens to be syntatically valid.
The compiler is evaluating each sequence point in turn within the parenthesis and the result is the final expression, WSA_FLAG_OVERLAPPED in the expression.
The comma operator , is a sequence point in C++. The expression to the left of the comma is fully evaluated before the expression to the right is. The result is always the value to the right. When you've got an expression of the form (x1, x2, x3, ..., xn) the result of the expression is always xn.
I am reading "C++ Primer (5th Edition)" and I've run in something I'm not sure I understand correctly.
The example is pretty much similar to one they gave in the book. Imagine we have some function that returns string (or any class that has non-static members):
string some_function(par1, par2) {
string str;
// some code
return str;
}
I know that you can use the return value of any function to access its members, i.e. something like this is valid:
auto size = some_function(arg1, arg2).size(); // or whatever member of class
However, since the dot operator . and function call operator () have left to right grouping and same precedence, the above expression should be something like this:
(some_function(arg1, arg2)).size()
I suppose I am right so far? The thing I don't understand here is order of evaluation. Since order of evaluation is not specified for . operator, it means that either some_function(arg1, arg2) or size() will be evaluated first. But how can it evaluate size() first if it doesn't know on which object is it working on? This implies that order of evaluation should be fixed from left to right, but it is not. How is this possible?
Another example is something like this:
cin.get().get();
Again, it seems like first cin.get() should be evaluated before second get() since it won't know on which object is it working, but this doesn't seem to be necessarily the case.
Operators of the same precedence are evaluated according to their associativity, which you correctly observe is left-to-right for the operator group containing the function call and element selection operators. Therefore, yes, given the expression
x = foo().bar();
The order of operations is
x = (((foo()).bar)());
accounting for relative precedence and associativity of all operators involved. No one writes code in that manner, though.
Likewise, given
cin.get().get()
the order of operations is
(((cin.get)()).get)()
, so yes, the precedence rules result in the cin.get() sub-expression being evaluated first, yielding the object to which the second . (and thence the rest of the expression) is applied.
Is there a way where I can assign the same value for different variables without constructing an array in a single statement?
For example, if I have variables a,b,c,d, and e, can I assign something like
a=b=c=d=e=10.0
?
I know that I can do in a single line:
a=10.0; b=10.0; c=10.0; d=10.0; e=10.0
But that is not I want since if I want to change the value 10.0 later to something else, I have to make the change everywhere.
The first version is not possible in Fortran. Following the (2008) Standard, an assignment is of the general form (ch. 7.2.1.1)
variable = expr
But why don't you try something like:
a=10.0; b=a; c=a; d=a; e=a
That way, you just need to change the value of a later on!
Come on Fortranners, you know you want to ...
equivalence(a,b,c,d,e)
Now all those rascals are going to have the same value at all times.
Perhaps:
real, parameter :: NamedConst = 10.0
a=NamedConst; b=NamedConst; c=NamedConst; d=NamedConst; e=NamedConst
Then if you should use the special value NamedConst in more than one line, there is clearly a single place to change its value.
You probably should consider to use an array instead of individual variables, especially if they serve similar purposes:
real :: myarray(5)
myarray(:) = 10.0
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.