When should we use sizeof with and without parentheses [duplicate] - c++

This question already has answers here:
What does sizeof without () do? [duplicate]
(5 answers)
Closed 8 years ago.
typedef struct rem{
int addr;
char addrbuf[32];
} foo;
Both of these codes return the same results
foo addr;
printf("size is: %d\n",sizeof addr);
printf("size is: %d\n",sizeof (foo));
size is: 36
size is: 36
But when should we use sizeof with and without parentheses?

When using sizeof with a type, you need parentheses around the type. When using it with an expression, you don't. But you can of course include them in this case as well, and you don't have to worry about operator precedence in such case. With uncommon operators such as this one, fewer people would be sure of the precedence, so clarity certainly helps.
So I'd say it's preferable to use them always.

[expr.sizeof]/1:
The operand is either an expression, which is an unevaluated operand
(Clause 5), or a parenthesized type-id.
Thus the parentheses are required for types only. If you prefer to use parentheses for clarity and consistency (as I do) you can always use them though, as parentheses around an expression form another expression.
The operator precedence of sizeof is not very well known and could cause irritations.
Also, for the sizeof... operator, you always have to use parentheses (another reason for consistency).

Related

Confusing use of sizeof(…) operator results

I was browsing some C++ code recently and I ran into the following line:
static char zsocket_name[sizeof((struct sockaddr_un*)0)->sun_path] = {};
… This is confusing, as it looks to me as if the result of the sizeof operator is being pointer-dereferenced to access a struct field named sun_path, and that value is to be used to size an array in static storage.
However, when I tried a simple snippet program to evaulate the expression sizeof((struct sockaddr_un*)0)->sun_path, it yields the size of the sun_path member of the sockaddr_un struct.
Clearly, that is what the author of the original line was intending; but I find it syntactically confusing as it looks like a pointer dereference on the result of the sizeof(…) operation.
What am I missing about this use of sizeof(…)? Why does this expression evaluate this way?
In C++, the sizeof operator has a form sizeof expression in addition to the more common sizeof(type), so this:
sizeof ((struct sockaddr_un*)0)->sun_path
is equivalent to this:
sizeof(decltype(((struct sockaddr_un*)0)->sun_path))
The former, albeit without whitespace, is what's written in the code you posted.
Note that a parenthesized expression is also an expression, so sizeof ((struct sockaddr_un*)0)->sun_path can also be written with extra parentheses: sizeof(((struct sockaddr_un*)0)->sun_path) — even though this looks like the sizeof(type) form, it's actually the sizeof expression form applied to a parenthesized expression.
The only thing you can't do is sizeof type, so this is invalid:
sizeof decltype(((struct sockaddr_un*)0)->sun_path)
A more modern way of getting at the struct's field in C++, without casting 0 to a pointer, would be to use declval:
sizeof std::declval<sockaddr_un>().sun_path
Your mistake is thinking that sizeof works like a function call, whereas it is actually an operator. There is no requirement to use () at all.
sizeof is actually an operator of the form sizeof expression and the () around expression are not required. The precedence of sizeof in expressions is actually equal to that of ++ and -- (prefix form), unary + and -, ! and ~ (logical and bitwise not), the (type) typecast, & (address of), unary * (pointer indirection), and (C from 2011) _Alignof. All of these have right-to-left associativity.
The only operators with higher precedence than sizeof are ++ and -- (suffix form), function call (()), [] array subscripting, . and -> to access struct members, and (for C only from 1999) compound literals (type){list}.
There is no sizeof(expression) form. sizeof x evaluates the size of the result of an expression x (without evaluating x). sizeof (x) evaluates the size of result of the expression (x), again without evaluating it. You happen to have an expression of the form sizeof a->b which (due to precedence rules) is equivalent to sizeof (a->b) and not to sizeof(a)->b (which would trigger a compilation error).

Ternary operator bit select: operator overload valid usage [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Operator overloading
I was wonder how can I over load the Conditional operator in cpp?
int a,b,c;
a=10;
b=11;
c = (a>b) ? a : b;
Is it possible?
You cannot overload the conditional operator.
Several operators cannot be overloaded. These operators take a name, rather than an object, as their right operand:
Direct member access (.)
Deference pointer to class member (.*)
Scope resolution (::)
Size of (sizeof)
The conditional operator (?:) also cannot be overloaded.
Additionally, the new typecast operators: static_cast<>, dynamic_cast<>, reinterpret_cast<>, and const_cast<>, and the # and ## preprocessor tokens cannot be overloaded.
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=23
No, you can't overload the conditional operator, since it's simply shorthand for a simple if..else block.
You can however overload the operators used in the condition, but not for primitive types such as int, like you have in your example above.

Why use this comma in this return statement? [duplicate]

This question already has answers here:
What does the comma operator , do?
(8 answers)
C++ -- return x,y; What is the point?
(18 answers)
Closed 6 years ago.
I understand what this C++ function does, but I don't understand why the return statement is written this way:
int intDivide(int num, int denom){
return assert(denom!=0), num/denom;
}
There is only one statement here, because there is only one ; but the comma confuses me. Why not write:
int intDivide(int num, int denom){
assert(denom!=0);
return num/denom;
}
Aside from "elegance" is there something to be gained in the first version?
What exactly is that comma doing anyway? Does it break a single statement into 2 parts such that essentially the above 2 versions are identical?
Although the code didn't seem to use constexpr, C++11 constexpr functions were constrained to have only one statement which had to be a return statement. To do the non-functional assertion and return a value there would be no other option than using the comma operator. With C++14 this constraint was removed, though.
I could imagine that the function was rewritten from a macro which originally read something like this
#define INT_DIVIDE(nom,denom) (assert(denom != 0), nom/denom)
The built-in comma operator simply sequences two expressions. The result of the expression is the second operand. The two functions are, indeed, equivalent. Note, that the comma operator can be overloaded. If it is, the expressions are not sequenced and the result is whatever the overload defines.
In practice the comma operator sometimes comes in quite handy. For example, it is quite common to use the comma operator when expanding a parameter pack: in some uses each of the expansions is required to produce a value and to avoid void results messing things up, the comma operator can be used to have a value. For example:
template <typename... T>
void g(T const& arg) {
std::initializer_list<bool>{ (f(arg), true)... };
}
This is a sort of 'syntactic sugar', which is expanded on in a similar question.
Basically the e1, e2 means evaluate e1, and then evaluate e2 - and the entire statement is the result of e2. It's a short and obfuscated (in my opinion) way of writing what you suggest. Maybe the writer is cheap on code lines.
From the C++ standard:
5.19 Comma operator [expr.comma]
1 The comma operator groups left-to-right.
expression:
assignment-expression
expression , assignment-expression
A pair of expressions separated by a comma is
evaluated left-to-right; the left expression is a discarded- value
expression (Clause 5).87 Every value computation and side effect
associated with the left expression is sequenced before every value
computation and side effect associated with the right expression. The
type and value of the result are the type and value of the right
operand; the result is of the same value category as its right
operand, and is a bit-field if its right operand is a glvalue and a
bit-field. If the value of the right operand is a temporary (12.2),
the result is that temporary.
Yes, the two versions are identical, except if the comma operator is overloaded, as #StoryTeller commented.

What is the "?" and ":" sequence actually called? [duplicate]

This question already has answers here:
What does the question mark character ('?') mean in C++?
(8 answers)
Closed 9 years ago.
This may be a bonehead question, but I cannot figure out what the ? exp : other_exp sequence is called.
Example:
int result = (true) ? 1 : 0;
I've tried using the Google machine, but it's hard to Googilize for something without knowing what it's called.
Thanks!
It is called the the conditional operator or alternativly the ternary operator as it a ternary operator (an operator which takes 3 operands (arguments)), and as it's usually the only operator, that does this.
It is also know as the inline if (iif), the ternary if or the question-mark-operator.
It is actualy a rather useful feature, as they are expressions, rather than statements, and can therefore be used, for instance in constexpr functions, assigments and such.
The C++ Syntax is;
logical-or-expression ? expression : assignment-expression
It's used as;
condition ? condition_is_true_expression : condition_is_false_expression
That is, if condition evaluates to true, the expression evaluates to condition_is_true_expression otherwise the expression evaluates to condition_is_false_expression.
So in your case, result would always be assigned the value 1.
Note 1; A common mistake that one makes while working with the conditional operator, is to forget that it has a fairly low operator precedence.
Note 2; Some functional languages doesn't provide this operator, as they have expression 'if...else' constructs, such as OCaml;
let value = if b then 1 else 2
Note 3; A funny use case, which is perfectly valid is using the conditional operator, to decide, which of two variable to assign a value to.
(condition ? x : y) = 1;
Notice the parentheses are necessary, as this is really what you get without them;
condition ? x : (y = 1);
They are called shorthand if-else or ternary operators.
See this article for more information.

Why sizeof int is wrong, while sizeof(int) is right?

We know that sizeof is an operator used for calculating the size of any datatype and expression, and when the operand is an expression, the parentheses can be omitted.
int main()
{
int a;
sizeof int;
sizeof( int );
sizeof a;
sizeof( a );
return 0;
}
the first usage of sizeof is wrong, while others are right.
When it is compiled using gcc, the following error message will be given:
main.c:5:9: error: expected expression before ‘int’
My question is why the C standard does not allow this kind of operation. Will sizeof int cause any ambiguity?
The following could be ambiguous:
sizeof int * + 1
Is that (sizeof (int*)) + 1, or (sizeof(int)) * (+1)?
Obviously the C language could have introduced a rule to resolve the ambiguity, but I can imagine why it didn't bother. With the language as it stands, a type specifier never appears "naked" in an expression, and so there is no need for rules to resolve whether that second * is part of the type or an arithmetic operator.
The existing grammar does already resolve the potential ambiguity of sizeof (int *) + 1. It is (sizeof(int*))+1, not sizeof((int*)(+1)).
C++ has a somewhat similar issue to resolve with function-style cast syntax. You can write int(0) and you can write typedef int *intptr; intptr(0);, but you can't write int*(0). In that case, the resolution is that the "naked" type must be a simple type name, it can't just be any old type id that might have spaces in it, or trailing punctuation. Maybe sizeof could have been defined with the same restriction, I'm not certain.
From C99 Standard
6.5.3.4.2
The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a
type.
In your case int is neither expression nor parenthesized name.
There are two ways to use the sizeof operator in C. The syntax is this:
C11 6.5.3 Unary operators
...
sizeof unary-expression
sizeof ( type-name )
Whenever you use a type as operand, you must have the parenthesis, by the syntax definition of the language. If you use sizeof on an expression, you don't need the parenthesis.
The C standard gives one such example of where you might want to use it on an expression:
sizeof array / sizeof array[0]
However, for the sake of consistency, and to avoid bugs related to operator precedence, I would personally advise to always use () no matter the situation.