What is happening in “? :”? I have no idea about the return type
I think ((1 ? (int)1 : (unsigned int)2) > -1)
results in 1
(true), but actually it is 0
(false) in Visual Studio 2017.
I think the value of (1 ? (int)1 : (unsigned int)2)
should be (int)1
, because 1 ?
is true, and 1 > -1
would be true.
I don't know the reason why the final result of this expression is false.
When I try casting like ((int)(1 ? (int)1 : (unsigned int)2) > -1)
, it returns 1
(true).
signed int test = -1;
signed int si = 1;
unsigned int ui = 2;
printf("%dn", ((1 ? si : ui) > test));
return 0;
I expect the output to be 1
, but the actual output is 0
.
c ternary-operator unsigned signed conditional-operator
add a comment |
I think ((1 ? (int)1 : (unsigned int)2) > -1)
results in 1
(true), but actually it is 0
(false) in Visual Studio 2017.
I think the value of (1 ? (int)1 : (unsigned int)2)
should be (int)1
, because 1 ?
is true, and 1 > -1
would be true.
I don't know the reason why the final result of this expression is false.
When I try casting like ((int)(1 ? (int)1 : (unsigned int)2) > -1)
, it returns 1
(true).
signed int test = -1;
signed int si = 1;
unsigned int ui = 2;
printf("%dn", ((1 ? si : ui) > test));
return 0;
I expect the output to be 1
, but the actual output is 0
.
c ternary-operator unsigned signed conditional-operator
7
The type of(WHATEVER ? (int)1 : (double)42)
is always the same. The type does not change when you changeWHATEVER
. See c99 6.5.15.
– pmg
Jan 6 at 14:30
1
Possible duplicate of Comparison operation on unsigned and signed integers
– manjy
Jan 6 at 14:36
5
@manjy: This is not a duplicate of that. That question, and its best answer, address binary operators. First,? :
is not a binary operator, and, regardless of the value of its first operand, the last two operands are not combined in an operation. It is true that the usual arithmetic conversions apply when? :
has arithmetic operands, but that question does not say that, since it is not discussing the? :
operator. (Additionally,? :
may have non-arithmetic operands.)
– Eric Postpischil
Jan 6 at 15:03
add a comment |
I think ((1 ? (int)1 : (unsigned int)2) > -1)
results in 1
(true), but actually it is 0
(false) in Visual Studio 2017.
I think the value of (1 ? (int)1 : (unsigned int)2)
should be (int)1
, because 1 ?
is true, and 1 > -1
would be true.
I don't know the reason why the final result of this expression is false.
When I try casting like ((int)(1 ? (int)1 : (unsigned int)2) > -1)
, it returns 1
(true).
signed int test = -1;
signed int si = 1;
unsigned int ui = 2;
printf("%dn", ((1 ? si : ui) > test));
return 0;
I expect the output to be 1
, but the actual output is 0
.
c ternary-operator unsigned signed conditional-operator
I think ((1 ? (int)1 : (unsigned int)2) > -1)
results in 1
(true), but actually it is 0
(false) in Visual Studio 2017.
I think the value of (1 ? (int)1 : (unsigned int)2)
should be (int)1
, because 1 ?
is true, and 1 > -1
would be true.
I don't know the reason why the final result of this expression is false.
When I try casting like ((int)(1 ? (int)1 : (unsigned int)2) > -1)
, it returns 1
(true).
signed int test = -1;
signed int si = 1;
unsigned int ui = 2;
printf("%dn", ((1 ? si : ui) > test));
return 0;
I expect the output to be 1
, but the actual output is 0
.
c ternary-operator unsigned signed conditional-operator
c ternary-operator unsigned signed conditional-operator
edited Jan 7 at 3:16
Deduplicator
34.4k64888
34.4k64888
asked Jan 6 at 14:15
BellSnowBellSnow
995
995
7
The type of(WHATEVER ? (int)1 : (double)42)
is always the same. The type does not change when you changeWHATEVER
. See c99 6.5.15.
– pmg
Jan 6 at 14:30
1
Possible duplicate of Comparison operation on unsigned and signed integers
– manjy
Jan 6 at 14:36
5
@manjy: This is not a duplicate of that. That question, and its best answer, address binary operators. First,? :
is not a binary operator, and, regardless of the value of its first operand, the last two operands are not combined in an operation. It is true that the usual arithmetic conversions apply when? :
has arithmetic operands, but that question does not say that, since it is not discussing the? :
operator. (Additionally,? :
may have non-arithmetic operands.)
– Eric Postpischil
Jan 6 at 15:03
add a comment |
7
The type of(WHATEVER ? (int)1 : (double)42)
is always the same. The type does not change when you changeWHATEVER
. See c99 6.5.15.
– pmg
Jan 6 at 14:30
1
Possible duplicate of Comparison operation on unsigned and signed integers
– manjy
Jan 6 at 14:36
5
@manjy: This is not a duplicate of that. That question, and its best answer, address binary operators. First,? :
is not a binary operator, and, regardless of the value of its first operand, the last two operands are not combined in an operation. It is true that the usual arithmetic conversions apply when? :
has arithmetic operands, but that question does not say that, since it is not discussing the? :
operator. (Additionally,? :
may have non-arithmetic operands.)
– Eric Postpischil
Jan 6 at 15:03
7
7
The type of
(WHATEVER ? (int)1 : (double)42)
is always the same. The type does not change when you change WHATEVER
. See c99 6.5.15.– pmg
Jan 6 at 14:30
The type of
(WHATEVER ? (int)1 : (double)42)
is always the same. The type does not change when you change WHATEVER
. See c99 6.5.15.– pmg
Jan 6 at 14:30
1
1
Possible duplicate of Comparison operation on unsigned and signed integers
– manjy
Jan 6 at 14:36
Possible duplicate of Comparison operation on unsigned and signed integers
– manjy
Jan 6 at 14:36
5
5
@manjy: This is not a duplicate of that. That question, and its best answer, address binary operators. First,
? :
is not a binary operator, and, regardless of the value of its first operand, the last two operands are not combined in an operation. It is true that the usual arithmetic conversions apply when ? :
has arithmetic operands, but that question does not say that, since it is not discussing the ? :
operator. (Additionally, ? :
may have non-arithmetic operands.)– Eric Postpischil
Jan 6 at 15:03
@manjy: This is not a duplicate of that. That question, and its best answer, address binary operators. First,
? :
is not a binary operator, and, regardless of the value of its first operand, the last two operands are not combined in an operation. It is true that the usual arithmetic conversions apply when ? :
has arithmetic operands, but that question does not say that, since it is not discussing the ? :
operator. (Additionally, ? :
may have non-arithmetic operands.)– Eric Postpischil
Jan 6 at 15:03
add a comment |
4 Answers
4
active
oldest
votes
The type of a ? b : c
is not dependent on a
. It is determined unconditionally by the types of b
and c
. The full rules are complicated, but, for arithmetic operands, the type is determined by the usual arithmetic conversions. In effect, the two operands are converted to a common type. For int
and unsigned int
, the resulting type is unsigned int
.
The conditional operator, ? :
is described in clause 6.5.15 of the C 2018 standard. Paragraph 4 says the result is “converted to the type described below.”
Paragraph 5 describes the result for arithmetic types, structures, and unions:
If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result. If both the operands have structure or union type, the result has that type. If both operands have void type, the result has void type.
Arithmetic types are integer and floating-point types, per 6.2.5 18. (These include both real and complex types.) The usual arithmetic conversions are described in 6.3.1.8 1, which are (in my summary, not quoted):
- If either is a complex type, the result is complex, and the remaining rules describe the type of the real and imaginary parts. Otherwise, the result is real, and the remaining rules describe its type.
- If either is
long double
, the result islong double
. - Otherwise, if either is
double
, the result isdouble
. - Otherwise, if either is
float
, the result isfloat
. - Otherwise, the integer promotions are applied to each operand (these are specified in 6.3.1.1 2), and then the two types are converted to a common integer type. The full rules for this are somewhat complicated, use a concept of rank that requires some explanation, and cover some esoteric situations, so I will just summarize them for normal situations: If both types are
int
or narrower (meaning fewer bits or the same number of bits but signed instead of unsigned), the result isint
. Otherwise, if both areunsigned int
or narrower, the result isunsigned int
. Otherwise, the result is the wider type.
The structure, union, and void rules are clear: The two operands must have the same type, and that is the result.
Paragraph 6 describes the result for pointers:
If both the second and third operands are pointers or one is a null pointer constant and the other is a pointer, the result type is a pointer to a type qualified with all the type qualifiers of the types referenced by both operands. Furthermore, if both operands are pointers to compatible types or to differently qualified versions of compatible types, the result type is a pointer to an appropriately qualified version of the composite type; if one operand is a null pointer constant, the result has the type of the other operand; otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void.
In summary, that says:
- If either operand has qualifiers (
const
,volatile
,restrict
, or_Atomic
), include those in the result type. - If the two types are different but compatible (such as an array of unknown size and an array of known size, both with the same type of elements), then combine the two types. (Other possibilities for combining, besides array size, include the elements of the arrays being different but compatible types, a function with and without a parameter list, and the parameters to functions being different but compatible types.)
So, according to your answer, is it right to understand that the result type of my code is "unsigned int" because of the sentence, "If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result." ?
– BellSnow
Jan 6 at 15:08
@BellSnow: Yes.
– Eric Postpischil
Jan 6 at 15:44
add a comment |
You should not mix signed and unsigned values unless you perfectly know what is unfolding (and you want that behavior) [checkout here why]. Behind the scenes, as you have an unsigned
number in your expression, C is evaluated your greater-than operator to an unsigned integer >
. Therefore, your comparison will not evaluate true
as "unsigned -1
" is greater than your unsigned 1
.
1
OP did not think they were mixing signed and unsigned values. They believed they were getting either a signed or an unsigned value from? :
; they did not know that? :
combines the types.
– Eric Postpischil
Jan 6 at 14:59
Indeed. I was writing in a general sense.
– delirium
Jan 6 at 15:01
1
Your advice is very reasonable, mixing signed and unsigned types in arithmetic expressions should be avoided because the rules are complicated and somewhat counterintuitive. As a matter of fact, having anunsigned
operand may not always force anunsigned
resulting type: for example((1 ? (long)1 : (unsigned)2) > -1)
may produce a different result on different platforms, depending on the respective sizes of typesint
andlong
.
– chqrlie
Jan 6 at 15:44
@chqrlie exactly! That behavior is even harder to bug.
– delirium
Jan 7 at 10:48
@delirium: to bug or to debug, that is the question...:)
– chqrlie
Jan 7 at 13:46
add a comment |
The result of your ?:
operator has unsigned type, since it is the common type for int
and unsigned
(your 2nd and 3rd operands). The result has the "expected" value of 1
, but its type is unsigned
.
The rest has nothing to do with ?:
at all. It is well-described in numerous answers for this frequently asked question: Comparison operation on unsigned and signed integers
add a comment |
Just to put a number on it, if I drop this code:
unsigned x = (unsigned)-1;
into a program I'm debugging right now, X has the value 4294967295 (UINT_MAX), i.e. your program "sees" the comparison as something like this:
((1 ? (int)1 : (unsigned int)2) > 4294967296)
(Would have entered this as a comment, but I don't have the reputation.)
just use-1U
or2U
instead of(unsigned)-1;
...
– phuclv
Jan 7 at 1:26
1
This is incorrect,4294967296
has typelong long
(on common systems) . Maybe you meant to write4294967295
there? (But if so, add theu
suffix)
– M.M
Jan 7 at 4:19
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54062382%2fwhat-is-happening-in-i-have-no-idea-about-the-return-type%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
The type of a ? b : c
is not dependent on a
. It is determined unconditionally by the types of b
and c
. The full rules are complicated, but, for arithmetic operands, the type is determined by the usual arithmetic conversions. In effect, the two operands are converted to a common type. For int
and unsigned int
, the resulting type is unsigned int
.
The conditional operator, ? :
is described in clause 6.5.15 of the C 2018 standard. Paragraph 4 says the result is “converted to the type described below.”
Paragraph 5 describes the result for arithmetic types, structures, and unions:
If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result. If both the operands have structure or union type, the result has that type. If both operands have void type, the result has void type.
Arithmetic types are integer and floating-point types, per 6.2.5 18. (These include both real and complex types.) The usual arithmetic conversions are described in 6.3.1.8 1, which are (in my summary, not quoted):
- If either is a complex type, the result is complex, and the remaining rules describe the type of the real and imaginary parts. Otherwise, the result is real, and the remaining rules describe its type.
- If either is
long double
, the result islong double
. - Otherwise, if either is
double
, the result isdouble
. - Otherwise, if either is
float
, the result isfloat
. - Otherwise, the integer promotions are applied to each operand (these are specified in 6.3.1.1 2), and then the two types are converted to a common integer type. The full rules for this are somewhat complicated, use a concept of rank that requires some explanation, and cover some esoteric situations, so I will just summarize them for normal situations: If both types are
int
or narrower (meaning fewer bits or the same number of bits but signed instead of unsigned), the result isint
. Otherwise, if both areunsigned int
or narrower, the result isunsigned int
. Otherwise, the result is the wider type.
The structure, union, and void rules are clear: The two operands must have the same type, and that is the result.
Paragraph 6 describes the result for pointers:
If both the second and third operands are pointers or one is a null pointer constant and the other is a pointer, the result type is a pointer to a type qualified with all the type qualifiers of the types referenced by both operands. Furthermore, if both operands are pointers to compatible types or to differently qualified versions of compatible types, the result type is a pointer to an appropriately qualified version of the composite type; if one operand is a null pointer constant, the result has the type of the other operand; otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void.
In summary, that says:
- If either operand has qualifiers (
const
,volatile
,restrict
, or_Atomic
), include those in the result type. - If the two types are different but compatible (such as an array of unknown size and an array of known size, both with the same type of elements), then combine the two types. (Other possibilities for combining, besides array size, include the elements of the arrays being different but compatible types, a function with and without a parameter list, and the parameters to functions being different but compatible types.)
So, according to your answer, is it right to understand that the result type of my code is "unsigned int" because of the sentence, "If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result." ?
– BellSnow
Jan 6 at 15:08
@BellSnow: Yes.
– Eric Postpischil
Jan 6 at 15:44
add a comment |
The type of a ? b : c
is not dependent on a
. It is determined unconditionally by the types of b
and c
. The full rules are complicated, but, for arithmetic operands, the type is determined by the usual arithmetic conversions. In effect, the two operands are converted to a common type. For int
and unsigned int
, the resulting type is unsigned int
.
The conditional operator, ? :
is described in clause 6.5.15 of the C 2018 standard. Paragraph 4 says the result is “converted to the type described below.”
Paragraph 5 describes the result for arithmetic types, structures, and unions:
If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result. If both the operands have structure or union type, the result has that type. If both operands have void type, the result has void type.
Arithmetic types are integer and floating-point types, per 6.2.5 18. (These include both real and complex types.) The usual arithmetic conversions are described in 6.3.1.8 1, which are (in my summary, not quoted):
- If either is a complex type, the result is complex, and the remaining rules describe the type of the real and imaginary parts. Otherwise, the result is real, and the remaining rules describe its type.
- If either is
long double
, the result islong double
. - Otherwise, if either is
double
, the result isdouble
. - Otherwise, if either is
float
, the result isfloat
. - Otherwise, the integer promotions are applied to each operand (these are specified in 6.3.1.1 2), and then the two types are converted to a common integer type. The full rules for this are somewhat complicated, use a concept of rank that requires some explanation, and cover some esoteric situations, so I will just summarize them for normal situations: If both types are
int
or narrower (meaning fewer bits or the same number of bits but signed instead of unsigned), the result isint
. Otherwise, if both areunsigned int
or narrower, the result isunsigned int
. Otherwise, the result is the wider type.
The structure, union, and void rules are clear: The two operands must have the same type, and that is the result.
Paragraph 6 describes the result for pointers:
If both the second and third operands are pointers or one is a null pointer constant and the other is a pointer, the result type is a pointer to a type qualified with all the type qualifiers of the types referenced by both operands. Furthermore, if both operands are pointers to compatible types or to differently qualified versions of compatible types, the result type is a pointer to an appropriately qualified version of the composite type; if one operand is a null pointer constant, the result has the type of the other operand; otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void.
In summary, that says:
- If either operand has qualifiers (
const
,volatile
,restrict
, or_Atomic
), include those in the result type. - If the two types are different but compatible (such as an array of unknown size and an array of known size, both with the same type of elements), then combine the two types. (Other possibilities for combining, besides array size, include the elements of the arrays being different but compatible types, a function with and without a parameter list, and the parameters to functions being different but compatible types.)
So, according to your answer, is it right to understand that the result type of my code is "unsigned int" because of the sentence, "If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result." ?
– BellSnow
Jan 6 at 15:08
@BellSnow: Yes.
– Eric Postpischil
Jan 6 at 15:44
add a comment |
The type of a ? b : c
is not dependent on a
. It is determined unconditionally by the types of b
and c
. The full rules are complicated, but, for arithmetic operands, the type is determined by the usual arithmetic conversions. In effect, the two operands are converted to a common type. For int
and unsigned int
, the resulting type is unsigned int
.
The conditional operator, ? :
is described in clause 6.5.15 of the C 2018 standard. Paragraph 4 says the result is “converted to the type described below.”
Paragraph 5 describes the result for arithmetic types, structures, and unions:
If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result. If both the operands have structure or union type, the result has that type. If both operands have void type, the result has void type.
Arithmetic types are integer and floating-point types, per 6.2.5 18. (These include both real and complex types.) The usual arithmetic conversions are described in 6.3.1.8 1, which are (in my summary, not quoted):
- If either is a complex type, the result is complex, and the remaining rules describe the type of the real and imaginary parts. Otherwise, the result is real, and the remaining rules describe its type.
- If either is
long double
, the result islong double
. - Otherwise, if either is
double
, the result isdouble
. - Otherwise, if either is
float
, the result isfloat
. - Otherwise, the integer promotions are applied to each operand (these are specified in 6.3.1.1 2), and then the two types are converted to a common integer type. The full rules for this are somewhat complicated, use a concept of rank that requires some explanation, and cover some esoteric situations, so I will just summarize them for normal situations: If both types are
int
or narrower (meaning fewer bits or the same number of bits but signed instead of unsigned), the result isint
. Otherwise, if both areunsigned int
or narrower, the result isunsigned int
. Otherwise, the result is the wider type.
The structure, union, and void rules are clear: The two operands must have the same type, and that is the result.
Paragraph 6 describes the result for pointers:
If both the second and third operands are pointers or one is a null pointer constant and the other is a pointer, the result type is a pointer to a type qualified with all the type qualifiers of the types referenced by both operands. Furthermore, if both operands are pointers to compatible types or to differently qualified versions of compatible types, the result type is a pointer to an appropriately qualified version of the composite type; if one operand is a null pointer constant, the result has the type of the other operand; otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void.
In summary, that says:
- If either operand has qualifiers (
const
,volatile
,restrict
, or_Atomic
), include those in the result type. - If the two types are different but compatible (such as an array of unknown size and an array of known size, both with the same type of elements), then combine the two types. (Other possibilities for combining, besides array size, include the elements of the arrays being different but compatible types, a function with and without a parameter list, and the parameters to functions being different but compatible types.)
The type of a ? b : c
is not dependent on a
. It is determined unconditionally by the types of b
and c
. The full rules are complicated, but, for arithmetic operands, the type is determined by the usual arithmetic conversions. In effect, the two operands are converted to a common type. For int
and unsigned int
, the resulting type is unsigned int
.
The conditional operator, ? :
is described in clause 6.5.15 of the C 2018 standard. Paragraph 4 says the result is “converted to the type described below.”
Paragraph 5 describes the result for arithmetic types, structures, and unions:
If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result. If both the operands have structure or union type, the result has that type. If both operands have void type, the result has void type.
Arithmetic types are integer and floating-point types, per 6.2.5 18. (These include both real and complex types.) The usual arithmetic conversions are described in 6.3.1.8 1, which are (in my summary, not quoted):
- If either is a complex type, the result is complex, and the remaining rules describe the type of the real and imaginary parts. Otherwise, the result is real, and the remaining rules describe its type.
- If either is
long double
, the result islong double
. - Otherwise, if either is
double
, the result isdouble
. - Otherwise, if either is
float
, the result isfloat
. - Otherwise, the integer promotions are applied to each operand (these are specified in 6.3.1.1 2), and then the two types are converted to a common integer type. The full rules for this are somewhat complicated, use a concept of rank that requires some explanation, and cover some esoteric situations, so I will just summarize them for normal situations: If both types are
int
or narrower (meaning fewer bits or the same number of bits but signed instead of unsigned), the result isint
. Otherwise, if both areunsigned int
or narrower, the result isunsigned int
. Otherwise, the result is the wider type.
The structure, union, and void rules are clear: The two operands must have the same type, and that is the result.
Paragraph 6 describes the result for pointers:
If both the second and third operands are pointers or one is a null pointer constant and the other is a pointer, the result type is a pointer to a type qualified with all the type qualifiers of the types referenced by both operands. Furthermore, if both operands are pointers to compatible types or to differently qualified versions of compatible types, the result type is a pointer to an appropriately qualified version of the composite type; if one operand is a null pointer constant, the result has the type of the other operand; otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void.
In summary, that says:
- If either operand has qualifiers (
const
,volatile
,restrict
, or_Atomic
), include those in the result type. - If the two types are different but compatible (such as an array of unknown size and an array of known size, both with the same type of elements), then combine the two types. (Other possibilities for combining, besides array size, include the elements of the arrays being different but compatible types, a function with and without a parameter list, and the parameters to functions being different but compatible types.)
edited Jan 6 at 15:07
answered Jan 6 at 14:32
Eric PostpischilEric Postpischil
72.8k879158
72.8k879158
So, according to your answer, is it right to understand that the result type of my code is "unsigned int" because of the sentence, "If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result." ?
– BellSnow
Jan 6 at 15:08
@BellSnow: Yes.
– Eric Postpischil
Jan 6 at 15:44
add a comment |
So, according to your answer, is it right to understand that the result type of my code is "unsigned int" because of the sentence, "If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result." ?
– BellSnow
Jan 6 at 15:08
@BellSnow: Yes.
– Eric Postpischil
Jan 6 at 15:44
So, according to your answer, is it right to understand that the result type of my code is "unsigned int" because of the sentence, "If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result." ?
– BellSnow
Jan 6 at 15:08
So, according to your answer, is it right to understand that the result type of my code is "unsigned int" because of the sentence, "If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result." ?
– BellSnow
Jan 6 at 15:08
@BellSnow: Yes.
– Eric Postpischil
Jan 6 at 15:44
@BellSnow: Yes.
– Eric Postpischil
Jan 6 at 15:44
add a comment |
You should not mix signed and unsigned values unless you perfectly know what is unfolding (and you want that behavior) [checkout here why]. Behind the scenes, as you have an unsigned
number in your expression, C is evaluated your greater-than operator to an unsigned integer >
. Therefore, your comparison will not evaluate true
as "unsigned -1
" is greater than your unsigned 1
.
1
OP did not think they were mixing signed and unsigned values. They believed they were getting either a signed or an unsigned value from? :
; they did not know that? :
combines the types.
– Eric Postpischil
Jan 6 at 14:59
Indeed. I was writing in a general sense.
– delirium
Jan 6 at 15:01
1
Your advice is very reasonable, mixing signed and unsigned types in arithmetic expressions should be avoided because the rules are complicated and somewhat counterintuitive. As a matter of fact, having anunsigned
operand may not always force anunsigned
resulting type: for example((1 ? (long)1 : (unsigned)2) > -1)
may produce a different result on different platforms, depending on the respective sizes of typesint
andlong
.
– chqrlie
Jan 6 at 15:44
@chqrlie exactly! That behavior is even harder to bug.
– delirium
Jan 7 at 10:48
@delirium: to bug or to debug, that is the question...:)
– chqrlie
Jan 7 at 13:46
add a comment |
You should not mix signed and unsigned values unless you perfectly know what is unfolding (and you want that behavior) [checkout here why]. Behind the scenes, as you have an unsigned
number in your expression, C is evaluated your greater-than operator to an unsigned integer >
. Therefore, your comparison will not evaluate true
as "unsigned -1
" is greater than your unsigned 1
.
1
OP did not think they were mixing signed and unsigned values. They believed they were getting either a signed or an unsigned value from? :
; they did not know that? :
combines the types.
– Eric Postpischil
Jan 6 at 14:59
Indeed. I was writing in a general sense.
– delirium
Jan 6 at 15:01
1
Your advice is very reasonable, mixing signed and unsigned types in arithmetic expressions should be avoided because the rules are complicated and somewhat counterintuitive. As a matter of fact, having anunsigned
operand may not always force anunsigned
resulting type: for example((1 ? (long)1 : (unsigned)2) > -1)
may produce a different result on different platforms, depending on the respective sizes of typesint
andlong
.
– chqrlie
Jan 6 at 15:44
@chqrlie exactly! That behavior is even harder to bug.
– delirium
Jan 7 at 10:48
@delirium: to bug or to debug, that is the question...:)
– chqrlie
Jan 7 at 13:46
add a comment |
You should not mix signed and unsigned values unless you perfectly know what is unfolding (and you want that behavior) [checkout here why]. Behind the scenes, as you have an unsigned
number in your expression, C is evaluated your greater-than operator to an unsigned integer >
. Therefore, your comparison will not evaluate true
as "unsigned -1
" is greater than your unsigned 1
.
You should not mix signed and unsigned values unless you perfectly know what is unfolding (and you want that behavior) [checkout here why]. Behind the scenes, as you have an unsigned
number in your expression, C is evaluated your greater-than operator to an unsigned integer >
. Therefore, your comparison will not evaluate true
as "unsigned -1
" is greater than your unsigned 1
.
answered Jan 6 at 14:38
deliriumdelirium
638518
638518
1
OP did not think they were mixing signed and unsigned values. They believed they were getting either a signed or an unsigned value from? :
; they did not know that? :
combines the types.
– Eric Postpischil
Jan 6 at 14:59
Indeed. I was writing in a general sense.
– delirium
Jan 6 at 15:01
1
Your advice is very reasonable, mixing signed and unsigned types in arithmetic expressions should be avoided because the rules are complicated and somewhat counterintuitive. As a matter of fact, having anunsigned
operand may not always force anunsigned
resulting type: for example((1 ? (long)1 : (unsigned)2) > -1)
may produce a different result on different platforms, depending on the respective sizes of typesint
andlong
.
– chqrlie
Jan 6 at 15:44
@chqrlie exactly! That behavior is even harder to bug.
– delirium
Jan 7 at 10:48
@delirium: to bug or to debug, that is the question...:)
– chqrlie
Jan 7 at 13:46
add a comment |
1
OP did not think they were mixing signed and unsigned values. They believed they were getting either a signed or an unsigned value from? :
; they did not know that? :
combines the types.
– Eric Postpischil
Jan 6 at 14:59
Indeed. I was writing in a general sense.
– delirium
Jan 6 at 15:01
1
Your advice is very reasonable, mixing signed and unsigned types in arithmetic expressions should be avoided because the rules are complicated and somewhat counterintuitive. As a matter of fact, having anunsigned
operand may not always force anunsigned
resulting type: for example((1 ? (long)1 : (unsigned)2) > -1)
may produce a different result on different platforms, depending on the respective sizes of typesint
andlong
.
– chqrlie
Jan 6 at 15:44
@chqrlie exactly! That behavior is even harder to bug.
– delirium
Jan 7 at 10:48
@delirium: to bug or to debug, that is the question...:)
– chqrlie
Jan 7 at 13:46
1
1
OP did not think they were mixing signed and unsigned values. They believed they were getting either a signed or an unsigned value from
? :
; they did not know that ? :
combines the types.– Eric Postpischil
Jan 6 at 14:59
OP did not think they were mixing signed and unsigned values. They believed they were getting either a signed or an unsigned value from
? :
; they did not know that ? :
combines the types.– Eric Postpischil
Jan 6 at 14:59
Indeed. I was writing in a general sense.
– delirium
Jan 6 at 15:01
Indeed. I was writing in a general sense.
– delirium
Jan 6 at 15:01
1
1
Your advice is very reasonable, mixing signed and unsigned types in arithmetic expressions should be avoided because the rules are complicated and somewhat counterintuitive. As a matter of fact, having an
unsigned
operand may not always force an unsigned
resulting type: for example ((1 ? (long)1 : (unsigned)2) > -1)
may produce a different result on different platforms, depending on the respective sizes of types int
and long
.– chqrlie
Jan 6 at 15:44
Your advice is very reasonable, mixing signed and unsigned types in arithmetic expressions should be avoided because the rules are complicated and somewhat counterintuitive. As a matter of fact, having an
unsigned
operand may not always force an unsigned
resulting type: for example ((1 ? (long)1 : (unsigned)2) > -1)
may produce a different result on different platforms, depending on the respective sizes of types int
and long
.– chqrlie
Jan 6 at 15:44
@chqrlie exactly! That behavior is even harder to bug.
– delirium
Jan 7 at 10:48
@chqrlie exactly! That behavior is even harder to bug.
– delirium
Jan 7 at 10:48
@delirium: to bug or to debug, that is the question...
:)
– chqrlie
Jan 7 at 13:46
@delirium: to bug or to debug, that is the question...
:)
– chqrlie
Jan 7 at 13:46
add a comment |
The result of your ?:
operator has unsigned type, since it is the common type for int
and unsigned
(your 2nd and 3rd operands). The result has the "expected" value of 1
, but its type is unsigned
.
The rest has nothing to do with ?:
at all. It is well-described in numerous answers for this frequently asked question: Comparison operation on unsigned and signed integers
add a comment |
The result of your ?:
operator has unsigned type, since it is the common type for int
and unsigned
(your 2nd and 3rd operands). The result has the "expected" value of 1
, but its type is unsigned
.
The rest has nothing to do with ?:
at all. It is well-described in numerous answers for this frequently asked question: Comparison operation on unsigned and signed integers
add a comment |
The result of your ?:
operator has unsigned type, since it is the common type for int
and unsigned
(your 2nd and 3rd operands). The result has the "expected" value of 1
, but its type is unsigned
.
The rest has nothing to do with ?:
at all. It is well-described in numerous answers for this frequently asked question: Comparison operation on unsigned and signed integers
The result of your ?:
operator has unsigned type, since it is the common type for int
and unsigned
(your 2nd and 3rd operands). The result has the "expected" value of 1
, but its type is unsigned
.
The rest has nothing to do with ?:
at all. It is well-described in numerous answers for this frequently asked question: Comparison operation on unsigned and signed integers
edited Jan 7 at 4:18
answered Jan 7 at 3:21
AnTAnT
258k32414657
258k32414657
add a comment |
add a comment |
Just to put a number on it, if I drop this code:
unsigned x = (unsigned)-1;
into a program I'm debugging right now, X has the value 4294967295 (UINT_MAX), i.e. your program "sees" the comparison as something like this:
((1 ? (int)1 : (unsigned int)2) > 4294967296)
(Would have entered this as a comment, but I don't have the reputation.)
just use-1U
or2U
instead of(unsigned)-1;
...
– phuclv
Jan 7 at 1:26
1
This is incorrect,4294967296
has typelong long
(on common systems) . Maybe you meant to write4294967295
there? (But if so, add theu
suffix)
– M.M
Jan 7 at 4:19
add a comment |
Just to put a number on it, if I drop this code:
unsigned x = (unsigned)-1;
into a program I'm debugging right now, X has the value 4294967295 (UINT_MAX), i.e. your program "sees" the comparison as something like this:
((1 ? (int)1 : (unsigned int)2) > 4294967296)
(Would have entered this as a comment, but I don't have the reputation.)
just use-1U
or2U
instead of(unsigned)-1;
...
– phuclv
Jan 7 at 1:26
1
This is incorrect,4294967296
has typelong long
(on common systems) . Maybe you meant to write4294967295
there? (But if so, add theu
suffix)
– M.M
Jan 7 at 4:19
add a comment |
Just to put a number on it, if I drop this code:
unsigned x = (unsigned)-1;
into a program I'm debugging right now, X has the value 4294967295 (UINT_MAX), i.e. your program "sees" the comparison as something like this:
((1 ? (int)1 : (unsigned int)2) > 4294967296)
(Would have entered this as a comment, but I don't have the reputation.)
Just to put a number on it, if I drop this code:
unsigned x = (unsigned)-1;
into a program I'm debugging right now, X has the value 4294967295 (UINT_MAX), i.e. your program "sees" the comparison as something like this:
((1 ? (int)1 : (unsigned int)2) > 4294967296)
(Would have entered this as a comment, but I don't have the reputation.)
answered Jan 6 at 18:05
Bob CramBob Cram
495
495
just use-1U
or2U
instead of(unsigned)-1;
...
– phuclv
Jan 7 at 1:26
1
This is incorrect,4294967296
has typelong long
(on common systems) . Maybe you meant to write4294967295
there? (But if so, add theu
suffix)
– M.M
Jan 7 at 4:19
add a comment |
just use-1U
or2U
instead of(unsigned)-1;
...
– phuclv
Jan 7 at 1:26
1
This is incorrect,4294967296
has typelong long
(on common systems) . Maybe you meant to write4294967295
there? (But if so, add theu
suffix)
– M.M
Jan 7 at 4:19
just use
-1U
or 2U
instead of (unsigned)-1;
...– phuclv
Jan 7 at 1:26
just use
-1U
or 2U
instead of (unsigned)-1;
...– phuclv
Jan 7 at 1:26
1
1
This is incorrect,
4294967296
has type long long
(on common systems) . Maybe you meant to write 4294967295
there? (But if so, add the u
suffix)– M.M
Jan 7 at 4:19
This is incorrect,
4294967296
has type long long
(on common systems) . Maybe you meant to write 4294967295
there? (But if so, add the u
suffix)– M.M
Jan 7 at 4:19
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54062382%2fwhat-is-happening-in-i-have-no-idea-about-the-return-type%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
7
The type of
(WHATEVER ? (int)1 : (double)42)
is always the same. The type does not change when you changeWHATEVER
. See c99 6.5.15.– pmg
Jan 6 at 14:30
1
Possible duplicate of Comparison operation on unsigned and signed integers
– manjy
Jan 6 at 14:36
5
@manjy: This is not a duplicate of that. That question, and its best answer, address binary operators. First,
? :
is not a binary operator, and, regardless of the value of its first operand, the last two operands are not combined in an operation. It is true that the usual arithmetic conversions apply when? :
has arithmetic operands, but that question does not say that, since it is not discussing the? :
operator. (Additionally,? :
may have non-arithmetic operands.)– Eric Postpischil
Jan 6 at 15:03