Here's a code fragment from TC++PL Special Edition, p291:
void f1(T a)
{
T v[200];
T* p = &v[0];
p--; // please note (my comment)
*p = a; // oops: 'p' out of range, uncaught
++p;
*p = a; // ok
}
And here's an excerpt from p92:
"The result of taking the address of the element before the initial element
is undefined and should be avoided."
The author says, as I understand, it's ok with ++p after p--, which I think
contradict the statement in the excerpt. What do you think?
--
ES Kim
Jul 22 '05
42 2116
Alf P. Steinbach wrote: That is incorrect.
The result of the decrement is UB.
The result of incrementing that result is UB, not a "reincremen t".
Evidently, Alf is unclear on the concept of undefined behavior.
Alf,
Claiming the result of the increment is not "reincremen t"
implies that the behavior *is* defined.
The standard certainly allows the implementation
to define the behavior of the increment (in this case)
to be "reincremen t" and every standard compliant implementation
currently in existence defines it this way.
"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > wrote in message
news:cl******** **@nntp1.jpl.na sa.gov... Alf P. Steinbach wrote:
That is incorrect.
The result of the decrement is UB.
The result of incrementing that result is UB, not a "reincremen t".
Evidently, Alf is unclear on the concept of undefined behavior.
Alf,
Claiming the result of the increment is not "reincremen t" implies that the behavior *is* defined. The standard certainly allows the implementation to define the behavior of the increment (in this case) to be "reincremen t" and every standard compliant implementation currently in existence defines it this way.
Given the context, I think Alf's comment is correct. While UB really means
that anything can happen, including "reincremen t", the original assertion,
from my understanding, was that the behavior was always defined to be
"reincremen t" and only "reincremen t", which is not strictly true. But, as
Bill Clinton would say, that all depends upon what we mean by "is". ;-)
You're right, though, it could always work on a given implementation, and it
does work on most implementations (or virtually all implementations , as you
have maintained in the past). In the eyes of the standard, however, it's
just UB.
--
David Hilsee
David Hilsee wrote: Given the context, I think Alf's comment is correct. While UB really means that anything can happen, including "reincremen t", the original assertion, from my understanding, was that the behavior was always defined to be "reincremen t" and only "reincremen t", which is not strictly true. But, as Bill Clinton would say, that all depends upon what we mean by "is". ;-)
You're right, though, it could always work on a given implementation, and it does work on most implementations (or virtually all implementations , as you have maintained in the past). In the eyes of the standard, however, it's just UB.
Pointing to an invalid element, is undefined behaviour.
In reality, when the pointer gets reincremented, it does point to a
valid element and not somewhere else.
However "legally" speaking, the undefined behaviour invoked can even
change the value of the pointer itself and in such a case reincrementing
it will not point to the same object.
In general, when UB is invoked, the rest of the code is UB too.
So I have to agree with Alf in the end. :-)
--
Ioannis Vranos http://www23.brinkster.com/noicys
ES Kim wrote: There's no guarantee that "p is again pointing to a valid element". Even one UB will make every following well-defined statements undefined.
Yes, you are right.
--
Ioannis Vranos http://www23.brinkster.com/noicys
ES Kim posted: Here's a code fragment from TC++PL Special Edition, p291:
void f1(T a) { T v[200]; T* p = &v[0]; p--; // please note (my comment) *p = a; // oops: 'p' out of range, uncaught ++p; *p = a; // ok }
And here's an excerpt from p92:
"The result of taking the address of the element before the initial element is undefined and should be avoided."
The author says, as I understand, it's ok with ++p after p--, which I think contradict the statement in the excerpt. What do you think?
Well consider this:
If you use reinterpret_cas t to convert a pointer value to an unsigned
integral value (assuming the integral type is large enough to hold the
value) and then reconvert it back, then you're left with a valid pointer.
So while the following may be invalid:
int jack[6];
int* p = jack;
--p; //There may be overflow, for instance if p == 0
I'd advocate that the following *is* legal:
int jack[6];
int* p = jack;
unsigned long address = reinterpret_cas t<unsigned long const>(p);
--address;
//We don't have to check for overflow because it's
//guaranteed not to occur with unsigned integrals.
p = reinterpret_cas t<int* const>(address) ;
//Now 'p' points to one before the start of the array.
++address;
p = reinterpret_cas t<int* const>(address) ;
//And now we're back to the first element
In short, I would say that it's safe to increment or decrement a pointer
however you see fit, but just watch out for overflow! For instance:
int blah[50];
int* p = blah;
--p; //You can't be sure there's no overflow!
To simply say "it's UB to do this" even though there's a perfect logic
behind it to illustrate what's going on, is simply being formal and
pedantic.
-JKop
Alf P. Steinbach wrote: According to Google it's not in the errata list.
Executing those statements in sequence is definitely Undefined Behavior, and in particular the increment can not "fix" the earlier invoked UB.
Mail Bjarne and get the $30 prize money (or whatever the amount is... ;-)).
There are several examples like this. It would be a mistake to read the
textbook examples containing such UB as collectively well defined. They
are merely pedagogical devices containing inconsistencies for the sake of
brevity.
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
JKop wrote: Well consider this:
If you use reinterpret_cas t to convert a pointer value to an unsigned integral value (assuming the integral type is large enough to hold the value) and then reconvert it back, then you're left with a valid pointer.
Where did you read that?
From the C90 draft that I have:
"Conversion s that involve pointers (other than as permitted by the
constraints of $3.3.16.1) shall be specified by means of an explicit
cast; they have implementation-defined aspects: A pointer may be
converted to an integral type. The size of integer required and the
result are implementation-defined. If the space provided is not long
enough, the behavior is undefined. An arbitrary integer may be
converted to a pointer. The result is implementation-defined."
So while the following may be invalid:
int jack[6];
int* p = jack;
--p; //There may be overflow, for instance if p == 0
The above doesn't make sense.
I'd advocate that the following *is* legal:
int jack[6];
int* p = jack;
unsigned long address = reinterpret_cas t<unsigned long const>(p);
--address; //We don't have to check for overflow because it's //guaranteed not to occur with unsigned integrals.
p = reinterpret_cas t<int* const>(address) ;
//Now 'p' points to one before the start of the array.
++address;
p = reinterpret_cas t<int* const>(address) ;
//And now we're back to the first element
The above is non-sense. Consider this:
#include <iostream>
int main()
{
int array[10]={1,2,3,4,5,6,7 ,8,9,10};
char *p=reinterpret_ cast<char *>(&array[0]);
// Reads the first byte of every int in the array
for(unsigned i=0; i<10; ++i)
std::cout<<stat ic_cast<int>(p[i*sizeof(*array )]);
}
Or in other words p[5*sizeof(int)] refers to the 5th element of the int
array as opposed to p[5] which would read the 5th element of a char array.
--
Ioannis Vranos http://www23.brinkster.com/noicys From the C90 draft that I have:
Wrong language dude.
Anyway, regarding C++:
5.2.10
5 A value of integral type or enumeration type can be explicitly converted
to a pointer.64) A pointer converted
to an integer of sufficient size (if any such exists on the implementation)
and back to the same pointer type
will have its original value; mappings between pointers and integers are
otherwise implementation-defined.
-JKop
In message <cl**********@n ntp1.jpl.nasa.g ov>, E. Robert Tisdale
<E.************ **@jpl.nasa.gov > writes Alf P. Steinbach wrote:
That is incorrect. The result of the decrement is UB. The result of incrementing that result is UB, not a "reincremen t".
Evidently, Alf is unclear on the concept of undefined behavior.
Alf,
Claiming the result of the increment is not "reincremen t" implies that the behavior *is* defined. The standard certainly allows the implementation to define the behavior of the increment (in this case) to be "reincremen t" and every standard compliant implementation currently in existence defines it this way.
Do you have documentation for this stupendously sweeping claim?
Or are you merely suggesting that there are no standard-compliant
implementations ?
--
Richard Herring
"JKop" <NU**@NULL.NULL > wrote in message
news:1M******** ***********@new s.indigo.ie... If you use reinterpret_cas t to convert a pointer value to an unsigned integral value (assuming the integral type is large enough to hold the value) and then reconvert it back, then you're left with a valid pointer.
So while the following may be invalid:
int jack[6];
int* p = jack;
--p; //There may be overflow, for instance if p == 0
That is, if p is null pointer?
Surely you're joking, Mr. JKop. ;-)
I'd advocate that the following *is* legal:
[your logic snipped]
To simply say "it's UB to do this" even though there's a perfect logic behind it to illustrate what's going on, is simply being formal and pedantic.
Each implementation has its own "perfect" logic. The problem is, there are
some disagreements among them, and what we call UB is a kind of the
disagreement.
I admit I've never seen any implementation that causes trouble with the
original code, but that does not mean it will be ok all the time in the future.
--
ES Kim This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Guofu Chen |
last post by:
Hi,
In TC++PL, Chapter 10, there is an exercise which ask us to modify the
following program:
#include <iostream>
int main()
{
std::cout << "Hello, world!/n" ;
|
by: Wayne Shu |
last post by:
Hi everyone, I am reading B.S. 's TC++PL (special edition).
When I read chapter 11 Operator Overloading, I have two questions.
1. In subsection 11.2.2 paragraph 1, B.S. wrote "In particular,
operator =, operator, operator(), and operator-must be nonstatic
member function; this ensures that their first operands will be
lvalues". I know that these operators must be nonstatic member
functions, but why this ensure their first operands will...
|
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...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
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,...
| |
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...
|
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...
|
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...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |