473,803 Members | 3,095 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

contradiction in TC++PL?

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.
Jul 22 '05 #11
"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
Jul 22 '05 #12
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
Jul 22 '05 #13
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
Jul 22 '05 #14
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
Jul 22 '05 #15
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

Jul 22 '05 #16
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
Jul 22 '05 #17
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
Jul 22 '05 #18
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
Jul 22 '05 #19
"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
Jul 22 '05 #20

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

Similar topics

3
1745
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" ;
8
2978
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...
0
10550
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...
0
10317
jinu1996
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...
1
10295
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
10069
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
9125
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
7604
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
6844
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();...
0
5501
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...
0
5633
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.