473,748 Members | 10,058 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

~0 undefined?

Does ~0 yield undefined behavior? C++03 section 5 paragraph 5 seems to
suggest so:
If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable values
for its type, the behavior is undefined [...]
The description of unary ~ (C++03 section 5.3.1 paragraph 8):
The operand of — shall have integral or enumeration type; the
result is the one's complement of its operand. Integral promotions
are performed. The type of the result is the type of the promoted
operand. [...]
But perhaps "one's complement" means the value that type would have with
all bits inverted, rather than the mathematical result of inverting all
bits in the binary representation. For example, on a machine with 32-bit
int, does one's complement of 0 (attempt to) have the value 2^31-1, which
can't be represented in a signed int and is thus undefined, or does it
have the value of whatever a signed int with all set bits would have (-1
on a two's complement machine)?

I used the ~0 case for simplicity; in practice, this issue might occur
when ANDing with the complement of a mask, for example n&=~0x0F to clear
the low 4 bits of n, or ~n&0x0F to find the inverted low 4 bits of n.
Oct 20 '08 #1
22 2020
blargg wrote:
Does ~0 yield undefined behavior? C++03 section 5 paragraph 5 seems to
suggest so:
>If during the evaluation of an expression, the result is not
mathematical ly defined or not in the range of representable values
for its type, the behavior is undefined [...]

The description of unary ~ (C++03 section 5.3.1 paragraph 8):
>The operand of — shall have integral or enumeration type; the
result is the one's complement of its operand. Integral promotions
are performed. The type of the result is the type of the promoted
operand. [...]

But perhaps "one's complement" means the value that type would have with
all bits inverted, rather than the mathematical result of inverting all
bits in the binary representation. For example, on a machine with 32-bit
int, does one's complement of 0 (attempt to) have the value 2^31-1, which
can't be represented in a signed int and is thus undefined,
Uh... Sorry, could you perhaps elaborate, why (2^31 - 1) can't be
represented? Or did you mean (2^32 - 1)?

If the resulting value is greater than can be represented in 'int', the
compiler will create the code to promote it first to 'unsigned', then to
'long', then to 'unsigned long', IIRC. So, if ~0 cannot for some reason
be represented in an int, it might become the (unsigned){all bits set}
value.
or does it
have the value of whatever a signed int with all set bits would have (-1
on a two's complement machine)?
That's what I'd expect.
I used the ~0 case for simplicity; in practice, this issue might occur
when ANDing with the complement of a mask, for example n&=~0x0F to clear
the low 4 bits of n, or ~n&0x0F to find the inverted low 4 bits of n.
Actually, on 2's complement, we use -1 for the "all bits set"...
Perhaps we should switch to ~0 (more portable?)

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Oct 20 '08 #2
On Oct 20, 7:51*pm, blargg....@gish puppy.com (blargg) wrote:
Does ~0 yield undefined behavior?
No.
C++03 section 5 paragraph 5 seems to suggest so:
If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable
values for its type, the behavior is undefined [...]
The description of unary ~ (C++03 section 5.3.1 paragraph 8):
The operand of — shall have integral or enumeration type;
the result is the one's complement of its operand. Integral
promotions are performed. The type of the result is the type
of the promoted operand. [...]
But perhaps "one's complement" means the value that type would
have with all bits inverted, rather than the mathematical
result of inverting all bits in the binary representation.
It's not really that clear what to expect on a machine not using
2's complement, but at the worst, it's unspecified or
implementation defined---not undefined behavior. (In general, I
would recommend avoiding ~, | and & on signed types.)
For example, on a machine with 32-bit int, does one's
complement of 0 (attempt to) have the value 2^31-1, which
can't be represented in a signed int and is thus undefined, or
does it have the value of whatever a signed int with all set
bits would have (-1 on a two's complement machine)?
The wording is a bit sloppy, but what it doubtlessly means is
that you get a value with all bits set to one (in the specified
type). What that value is, of course, is probably
implementation dependent; it is -1 on a 2's complement machine,
but could very easily be 0 elsewhere.
I used the ~0 case for simplicity; in practice, this issue
might occur when ANDing with the complement of a mask, for
example n&=~0x0F to clear the low 4 bits of n, or ~n&0x0F to
find the inverted low 4 bits of n.
As long as the sign bit is 0, the behavior should be well
defined, with no ambiguities.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Oct 20 '08 #3
In article <gd**********@n ews.datemas.de> , Victor Bazarov
<v.********@com Acast.netwrote:
blargg wrote:
Does ~0 yield undefined behavior? C++03 section 5 paragraph 5 seems to
suggest so:
If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable values
for its type, the behavior is undefined [...]
The description of unary ~ (C++03 section 5.3.1 paragraph 8):
The operand of — shall have integral or enumeration type; the
result is the one's complement of its operand. Integral promotions
are performed. The type of the result is the type of the promoted
operand. [...]
But perhaps "one's complement" means the value that type would have with
all bits inverted, rather than the mathematical result of inverting all
bits in the binary representation. For example, on a machine with 32-bit
int, does one's complement of 0 (attempt to) have the value 2^31-1, which
can't be represented in a signed int and is thus undefined,

Uh... Sorry, could you perhaps elaborate, why (2^31 - 1) can't be
represented? Or did you mean (2^32 - 1)?
Yeah, (2^32 - 1); I noticed just after I posted.
If the resulting value is greater than can be represented in 'int', the
compiler will create the code to promote it first to 'unsigned', then to
'long', then to 'unsigned long', IIRC. So, if ~0 cannot for some reason
be represented in an int, it might become the (unsigned){all bits set}
value.
Not as I understand it, where this only occurs when selecting what type a
literal will be. If what you described were the case, the type of an
expression would depend on its run-time value, for example if i were an
int, the type of the expression i+1 would be an int unless i contained
INT_MAX, where it would be of type unsigned int. This is clearly not the
case, since C++ is statically-typed.
or does it
have the value of whatever a signed int with all set bits would have (-1
on a two's complement machine)?

That's what I'd expect.
The problem is that most compilers implement conversion of a value to a
signed int as a no-op, that is, simply to reinterpret the bits as being in
two's complement.
I used the ~0 case for simplicity; in practice, this issue might occur
when ANDing with the complement of a mask, for example n&=~0x0F to clear
the low 4 bits of n, or ~n&0x0F to find the inverted low 4 bits of n.

Actually, on 2's complement, we use -1 for the "all bits set"...
Perhaps we should switch to ~0 (more portable?)
It seems to me that ~0 is actually less-portable. As far as I know,
converting -1 to an unsigned type is guaranteed to give a value with all
bits set, since that conversion is guaranteed to give you a two's
complement representation in the unsigned result, even if the machine
doesn't use such a representation (C++03 section 4.7 paragraph 2).
Oct 20 '08 #4
Victor Bazarov wrote:
Actually, on 2's complement, we use -1 for the "all bits set"... Perhaps
we should switch to ~0 (more portable?)
But will it work properly? Assume that in some system 'long' is a
larger type than 'int'. Will this work?

long value1 = ~0;
unsigned long value2 = ~0;

What kind of promotion chain is ~0 subjected to here? Will 'value1'
and 'value2' end up having all bits set?
Oct 20 '08 #5
James Kanze wrote:
[..]
The wording is a bit sloppy, but what it doubtlessly means is
that you get a value with all bits set to one (in the specified
type). What that value is, of course, is probably
implementation dependent; it is -1 on a 2's complement machine,
but could very easily be 0 elsewhere.
Where? C++ only supports three representations , the 1's complement, the
2's complement, and the signed magnitude.
[..]
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Oct 20 '08 #6
Juha Nieminen wrote:
Victor Bazarov wrote:
>Actually, on 2's complement, we use -1 for the "all bits set"... Perhaps
we should switch to ~0 (more portable?)

But will it work properly? Assume that in some system 'long' is a
larger type than 'int'. Will this work?

long value1 = ~0;
unsigned long value2 = ~0;

What kind of promotion chain is ~0 subjected to here? Will 'value1'
and 'value2' end up having all bits set?
Probably not. It is generally better to use the literals of the same
type, IOW

long value1 = ~0L;
unsigned long value2 = ~0UL;

, to avoid specifically the situations where the result depends on some
implementation-defined behaviour[s].

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Oct 20 '08 #7
On Oct 20, 8:38*pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
blargg wrote:
Does ~0 yield undefined behavior? C++03 section 5 paragraph 5 seems to
suggest so:
If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable values
for its type, the behavior is undefined [...]
The description of unary ~ (C++03 section 5.3.1 paragraph 8):
The operand of — shall have integral or enumeration type; the
result is the one's complement of its operand. Integral promotions
are performed. The type of the result is the type of the promoted
operand. [...]
But perhaps "one's complement" means the value that type would have with
all bits inverted, rather than the mathematical result of inverting all
bits in the binary representation. For example, on a machine with 32-bit
int, does one's complement of 0 (attempt to) have the value 2^31-1, which
can't be represented in a signed int and is thus undefined,
Uh... *Sorry, could you perhaps elaborate, why (2^31 - 1) can't be
represented? *Or did you mean (2^32 - 1)?
If the resulting value is greater than can be represented in
'int', the compiler will create the code to promote it first
to 'unsigned', then to 'long', then to 'unsigned long', IIRC.
*So, if ~0 cannot for some reason be represented in an int, it
might become the (unsigned){all bits set} value.
No. That's the way the compiler behaves for integral literal
for an octal or hexadecimal constant. (For a decimal constant,
the results will never be unsigned.) In this case, the integral
literal is 0---which can't possibly overflow anything, and so
has type int. What we have here is an expression, with an
operator applied to an int. What blargg is doubtlessly
referring to is the statement in §5 that "If during the
evaluation of an expression, the result is not mathematically
defined or not in the range of representable values for its
type, the behavior is undefined, unless such an expression
appears where an integral constant expression is required
(5.19), in which case the program is ill-formed."

The problem here is that the "one's complement" operation
doesn't really define a numeric result, but rather a
manipulation on the underlying representation. So I don't think
that this statement can be applied: the ~ operator changes the
bits in the representation, and the "result" is whatever value
the changed bits happen to represent. Except that it's not
really too clear what that means, either; what happens if the
changed bits would be a trapping representation? (E.g. a 1's
complement machine that traps on negative 0's.)

Because of such issues, I tend to avoid using ~, | or & on
signed integral types.
*or does it
have the value of whatever a signed int with all set bits
would have (-1 on a two's complement machine)?
That's what I'd expect.
That's doubtlessly what was intended. On a two's complement
machine. Now try it on a one's complement machine which traps
negative 0's.

The C standard has cleared this up considerably. According to
the C99 standard:

If the implementation supports negative zeros, they
shall be generated only by:
-- the &, |, ^, ~, <<, and >operators with arguments
that produce such a value;
-- the +, -, *, /, and % operators where one argument
is a negative zero and the result is zero;
-- compound assignment operators based on the above
cases.
It is unspecified whether these cases actually generate
a negative zero or a normal zero, and whether a negative
zero becomes a normal zero when stored in an object.

If the implementation does not support negative zeros,
the behavior of the &, |, ^, ~, <<, and >operators
with arguments that would produce such a value is
undefined.

The second paragraph above is particularly significant: ~0
*is* undefined behavior on an implementation which doesn't
support negative zeros. (Note that the text immediately
preceding the above makes it clear that it is talking about
negative zero representations in one's complement or signed
magnitude; the "doesn't support negative zeros" only applies
in the case where they exist in the representation. )
I used the ~0 case for simplicity; in practice, this
issue might occur when ANDing with the complement of a
mask, for example n&=~0x0F to clear the low 4 bits of n,
or ~n&0x0F to find the inverted low 4 bits of n.
Actually, on 2's complement, we use -1 for the "all bits
set"... Perhaps we should switch to ~0 (more portable?)
If you're worried about bits, the *only* way you can be sure
of anything where the highest bit might not be 0 is to use
unsigned types. For signed types, ~0 can result in
undefined behavior. (In other words, ~0 is not portable, ~0U
is. As is -1, if that's what you want.)

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Oct 20 '08 #8
In article
<cd************ *************** *******@w24g200 0prd.googlegrou ps.com>, James
Kanze <ja*********@gm ail.comwrote:
blargg wrote:
>Does ~0 yield undefined behavior? C++03 section 5 paragraph 5 seems to
suggest so:
>>If during the evaluation of an expression, the result is not
mathematicall y defined or not in the range of representable values
for its type, the behavior is undefined [...]

The description of unary ~ (C++03 section 5.3.1 paragraph 8):
>>The operand of ~ shall have integral or enumeration type; the
result is the one's complement of its operand. Integral promotions
are performed. The type of the result is the type of the promoted
operand. [...]

But perhaps "one's complement" means the value that type would have with
all bits inverted, rather than the mathematical result of inverting all
bits in the binary representation. For example, on a machine with 32-bit
int, does one's complement of 0 (attempt to) have the value 2^31-1, which
can't be represented in a signed int and is thus undefined,
[...]
The problem here is that the "one's complement" operation doesn't
really define a numeric result, but rather a manipulation on the
underlying representation. So I don't think that this statement
[C++03 section 5 paragraph 5] can be applied: the ~ operator
changes the bits in the representation, and the "result" is
whatever value the changed bits happen to represent. Except that
it's not really too clear what that means, either; what happens if
the changed bits would be a trapping representation? (E.g. a 1's
complement machine that traps on negative 0's.)
So you're saying that n = ~n, where n is an int, could be implemented as

for ( size_t i = 0; i < sizeof n; ++i )
reinterpret_cas t<unsigned char*(&n) [i] ^= (unsigned char) -1;

where it's up to the implementation as to the new value n takes on. This
would imply that the following are guaranteed to hold true, regardless of
n's signedess or sign:

~~n == n
(n & ~n) == 0
(n ^ ~n) == ~0
(n & ~0) == n
(n & ~1) == n - (n & 1)

This is the interpretation I really hope is the case.
Because of such issues, I tend to avoid using ~, | or & on signed
integral types.
That would require ensuring all bitwise constants are unsigned, by
suffixing with a U, casting, or storing in an unsigned type before use,
which seems somewhat tedious. As in my example, even code for simply
testing the low bit would require a nasty U: n&1U.
Oct 20 '08 #9
On Oct 20, 9:42 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
James Kanze wrote:
[..]
The wording is a bit sloppy, but what it doubtlessly means
is that you get a value with all bits set to one (in the
specified type). What that value is, of course, is probably
implementation dependent; it is -1 on a 2's complement
machine, but could very easily be 0 elsewhere.
Where? C++ only supports three representations , the 1's
complement, the 2's complement, and the signed magnitude.
It's not at all clear what C++ supports. C++ took the defective
wording of C90, and modified it slightly to make it even worse.
C99 straightened it out, and does only allow three
representations . And as to where the result of ~0 would not be
-1, exactly what I said: "elsewhere [than on a 2's complement
architecture]". On 1's complement, it would be a negative 0.
(The C99 standard explicitly says that it may result in a
negative 0.) Depending on the implementation, a negative 0
either behaves exactly like a postive 0 in arithmetic operations
(but not bitwise operations), or it is undefined behavior.

So the answer to blargg's original question is, somewhat
surprisingly, that ~0 may result in undefined behavior. (Except
that since it is a constant expression, it doesn't cause
undefined behavior, but makes the program ill formed.)

More generally, the results of any of the bitwise operators --
~, |, &, ^, >or <<, or their <op>= forms -- may result in
undefined behavior. At least according to the C99 standard; the
C++ standard doesn't really say anything meaningful about what
they do.

I currently have a paper before the committee concerning defects
in the specification of the representation of integral types,
with the proposed correction to adopt the wording from C99
(can't see any reason for C and C++ to differ here); I'll update
it to consider these issues as well. (For example, in C99, ~ is
defined as the "bitwise complement", not the 1's complement.)

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Oct 21 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
13123
by: RU | last post by:
Hi, I am working on a porting project to port C/C++ application from unixware C++, AT&T Standard components to g++ with STL on Linux. This application has been working properly on Unixware/C++/AT&T componets environment. I have been able to compile all modules after making necessary changes in LINUX/gcc/STL environment. We have two templates defined XList and XMap.
1
11263
by: Stu | last post by:
I am trying to build the xerces shared library with 2.3.0 version of their source code on an AIX 5.1 32 bit machine with the following version of the g++ compiler /usr/local/bin/g++ -v Reading specs from /usr/local/lib/gcc-lib/powerpc-ibm-aix5.1.0.0/3.3.1/specs Configured with: ../gcc-3.3.1/configure --disable-nls Thread model: aix gcc version 3.3.1
4
6701
by: Mike | last post by:
I am having a problem when a field is spaces being undefined. I wasn't sure if the problem was Excel or Javascript, so I thought I would post here first. The users are able to select from a drop down list either a pre-existing Excel spreadsheet or a blank spreadsheet where they can enter the data. When they click the Store button I am using Javascript to validate the fields. If a particular field is not entered or has invalid data, then...
1
3149
by: Codemutant | last post by:
**** Post for FREE via your newsreader at post.usenet.com **** I just cannot find what is undefined in this code.
1
9612
by: Foolster41 | last post by:
I'm rather new to C++ programing. I'm using the dev-C++ program on a windows XP OS. I'm trying to compile the code for a multi user dungeon (MUD) called circle-mud. When I compile I get the following errors: ---- Compiler: Default compiler Building Makefile: "C:\EvoMud\circle-3.1\src\Makefile.win" Executing make...
13
3085
by: Don Vaillancourt | last post by:
What's going on with Javascript. At the beginning there was the "undefined" value which represented an object which really didn't exist then came the null keyword. But yesterday I stumbled across "null" string. I know that I will get an "undefined" when I try to retrieve something from the DOM which doesn't exist. I have used null myself to initialize or reset variables. But in which
4
4160
by: Chris Beall | last post by:
If you want your code to be bulletproof, do you have to explicitly check for the existence of any possibly-undefined variable? Example: window.outerHeight is defined by some browsers, but not others. It would therefore seem prudent, before using this variable, to do something like: if (typeof (window.outerHeight) != "undefined") { do stuff that refers to this variable } else { work around the fact that the variable isn't defined }
49
14517
by: matty | last post by:
Hi, I recently got very confused (well that's my life) about the "undefined" value. I looked in the FAQ and didn't see anything about it. On http://www.webreference.com/programming/javascript/gr/column9/ they say: <snip> The undefined property A relatively recent addition to JavaScript is the undefined property.
3
789
by: Michael Sgier | last post by:
Hi i get thousands of messages like below. How shall i resolve that? Thanks Mcihael Release/src/Utility/RawImage.o: In function `CMaskImage::CMaskImage(int, int, char const*)': RawImage.cpp:(.text+0x15dc): undefined reference to `popen(PFS*, char const*)'
45
4848
by: VK | last post by:
(see the post by ASM in the original thread; can be seen at <http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/3716384d8bfa1b0b> as an option) As that is not in relevance to "new Array() vs " question or to the array performance, I dared to move it to a new thread. Gecko takes undefined value strictly as per Book 4, Chapter 3, Song 9 of Books of ECMA :-)
0
8984
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9530
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9312
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9238
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8237
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6793
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4593
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3300
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2206
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.