Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #13047 > unrolled thread
| Started by | Quentin Pope <qp19433@hotmail.NOSPAM.com> |
|---|---|
| First post | 2011-11-10 20:21 +0000 |
| Last post | 2011-11-14 12:54 -0800 |
| Articles | 19 on this page of 59 — 20 participants |
Back to article view | Back to comp.lang.c
Typecasting Pointers on a 64 bit System Quentin Pope <qp19433@hotmail.NOSPAM.com> - 2011-11-10 20:21 +0000
Re: Typecasting Pointers on a 64 bit System Lauri Alanko <la@iki.fi> - 2011-11-10 20:29 +0000
Re: Typecasting Pointers on a 64 bit System Kaz Kylheku <kaz@kylheku.com> - 2011-11-10 20:51 +0000
Re: Typecasting Pointers on a 64 bit System Kaz Kylheku <kaz@kylheku.com> - 2011-11-10 20:58 +0000
Re: Typecasting Pointers on a 64 bit System James Kuyper <jameskuyper@verizon.net> - 2011-11-10 16:08 -0500
Re: Typecasting Pointers on a 64 bit System Kaz Kylheku <kaz@kylheku.com> - 2011-11-10 21:35 +0000
Re: Typecasting Pointers on a 64 bit System James Kuyper <jameskuyper@verizon.net> - 2011-11-10 17:18 -0500
Re: Typecasting Pointers on a 64 bit System Kaz Kylheku <kaz@kylheku.com> - 2011-11-10 23:14 +0000
Re: Typecasting Pointers on a 64 bit System Richard Damon <news.x.richarddamon@xoxy.net> - 2011-11-10 19:36 -0500
Re: Typecasting Pointers on a 64 bit System Ben Pfaff <blp@cs.stanford.edu> - 2011-11-10 12:32 -0800
Re: Typecasting Pointers on a 64 bit System James Kuyper <jameskuyper@verizon.net> - 2011-11-10 15:44 -0500
Re: Typecasting Pointers on a 64 bit System Keith Thompson <kst-u@mib.org> - 2011-11-10 12:58 -0800
Re: Typecasting Pointers on a 64 bit System blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> - 2011-11-17 15:53 +0000
Re: Typecasting Pointers on a 64 bit System Kaz Kylheku <kaz@kylheku.com> - 2011-11-10 20:45 +0000
Re: Typecasting Pointers on a 64 bit System Kaz Kylheku <kaz@kylheku.com> - 2011-11-10 21:00 +0000
Re: Typecasting Pointers on a 64 bit System Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-11-10 15:14 -0700
Re: Typecasting Pointers on a 64 bit System Ian Collins <ian-news@hotmail.com> - 2011-11-11 11:22 +1300
Re: Typecasting Pointers on a 64 bit System William Ahern <william@wilbur.25thandClement.com> - 2011-11-14 11:10 -0800
Re: Typecasting Pointers on a 64 bit System Ian Collins <ian-news@hotmail.com> - 2011-11-15 08:28 +1300
Re: Typecasting Pointers on a 64 bit System James Kuyper <jameskuyper@verizon.net> - 2011-11-14 14:48 -0500
Re: Typecasting Pointers on a 64 bit System Ian Collins <ian-news@hotmail.com> - 2011-11-15 10:15 +1300
Re: Typecasting Pointers on a 64 bit System jacob navia <jacob@spamsink.net> - 2011-11-14 22:18 +0100
Re: Typecasting Pointers on a 64 bit System Ian Collins <ian-news@hotmail.com> - 2011-11-15 10:26 +1300
Re: Typecasting Pointers on a 64 bit System James Kuyper <jameskuyper@verizon.net> - 2011-11-14 16:46 -0500
Re: Typecasting Pointers on a 64 bit System Ian Collins <ian-news@hotmail.com> - 2011-11-15 10:58 +1300
Re: Typecasting Pointers on a 64 bit System James Kuyper <jameskuyper@verizon.net> - 2011-11-14 17:15 -0500
Re: Typecasting Pointers on a 64 bit System blp@cs.stanford.edu (Ben Pfaff) - 2011-11-14 14:18 -0800
Re: Typecasting Pointers on a 64 bit System Ian Collins <ian-news@hotmail.com> - 2011-11-15 11:29 +1300
Re: Typecasting Pointers on a 64 bit System James Kuyper <jameskuyper@verizon.net> - 2011-11-14 18:14 -0500
Re: Typecasting Pointers on a 64 bit System Seebs <usenet-nospam@seebs.net> - 2011-11-14 23:01 +0000
Re: Typecasting Pointers on a 64 bit System Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-11-16 10:39 +0200
Re: Typecasting Pointers on a 64 bit System Seebs <usenet-nospam@seebs.net> - 2011-11-16 20:18 +0000
Re: Typecasting Pointers on a 64 bit System Fritz Wuehler <fritz@spamexpire-201111.rodent.frell.theremailer.net> - 2011-11-17 02:54 +0100
Re: Typecasting Pointers on a 64 bit System pete <pfiland@mindspring.com> - 2011-11-16 21:29 -0500
Re: Typecasting Pointers on a 64 bit System Seebs <usenet-nospam@seebs.net> - 2011-11-17 02:31 +0000
Re: Typecasting Pointers on a 64 bit System Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-11-18 14:31 +0200
Re: Typecasting Pointers on a 64 bit System Kaz Kylheku <kaz@kylheku.com> - 2011-11-17 02:44 +0000
Re: Typecasting Pointers on a 64 bit System Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-11-16 21:33 -0700
Re: Typecasting Pointers on a 64 bit System "io_x" <a@b.c.invalid> - 2011-11-17 04:01 +0100
Re: Typecasting Pointers on a 64 bit System blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> - 2011-11-17 15:46 +0000
Re: Typecasting Pointers on a 64 bit System Seebs <usenet-nospam@seebs.net> - 2011-11-17 18:48 +0000
Re: Typecasting Pointers on a 64 bit System blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> - 2011-11-18 14:48 +0000
Re: Typecasting Pointers on a 64 bit System Ian Collins <ian-news@hotmail.com> - 2011-11-15 14:37 +1300
Re: Typecasting Pointers on a 64 bit System Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-11-16 10:23 +0200
Re: Typecasting Pointers on a 64 bit System James Kuyper <jameskuyper@verizon.net> - 2011-11-16 06:53 -0500
Re: Typecasting Pointers on a 64 bit System James Kuyper <jameskuyper@verizon.net> - 2011-11-16 11:15 -0500
Re: Typecasting Pointers on a 64 bit System Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-11-16 17:08 +0000
Re: Typecasting Pointers on a 64 bit System Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-11-18 15:09 +0200
Re: Typecasting Pointers on a 64 bit System Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-11-18 14:24 +0200
Re: Typecasting Pointers on a 64 bit System James Kuyper <jameskuyper@verizon.net> - 2011-11-18 10:08 -0500
Re: Typecasting Pointers on a 64 bit System Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-11-18 17:52 +0200
Re: Typecasting Pointers on a 64 bit System Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-11-14 15:45 -0700
Re: Typecasting Pointers on a 64 bit System "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2011-11-10 15:19 -0800
Re: Typecasting Pointers on a 64 bit System Kaz Kylheku <kaz@kylheku.com> - 2011-11-10 23:41 +0000
Re: Typecasting Pointers on a 64 bit System Keith Thompson <kst-u@mib.org> - 2011-11-10 20:48 -0800
Re: Typecasting Pointers on a 64 bit System "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2011-11-14 03:39 -0800
Re: Typecasting Pointers on a 64 bit System Lauri Alanko <la@iki.fi> - 2011-11-14 13:08 +0000
Re: Typecasting Pointers on a 64 bit System James Kuyper <jameskuyper@verizon.net> - 2011-11-14 09:21 -0500
Re: Typecasting Pointers on a 64 bit System Keith Thompson <kst-u@mib.org> - 2011-11-14 12:54 -0800
Page 3 of 3 — ← Prev page 1 2 [3]
| From | Seebs <usenet-nospam@seebs.net> |
|---|---|
| Date | 2011-11-17 18:48 +0000 |
| Message-ID | <slrnjcakol.11i2.usenet-nospam@guild.seebs.net> |
| In reply to | #13558 |
On 2011-11-17, blmblm myrealbox.com <blmblm.myrealbox@gmail.com> wrote: > In article <slrnjc38ub.r7s.usenet-nospam@guild.seebs.net>, > Seebs <usenet-nospam@seebs.net> wrote: >> It is very easy for people who have finally been taught that it's not okay >> to return the address of a local variable to conclude that it's fine to >> pass the address of a local variable to a function you call. And you're >> *calling* pthread_create(), see. So that's fine. > Well, now *I*'m the one who's confused .... Are you saying > it's not fine? Yes. > I suppose if the function you call creates an > independent thread, and that thread persists longer than the one > that created it, yes, there could be a problem .... Was that > your point? Yes. But it's "fine" according to the simple rule people learn if they don't really *get* threaded programming. In the absence of threads, passing the address of a local variable to a function you call is generally safe. (Not, of course, if that function stashes the pointer for later use...) -s -- Copyright 2011, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated! I am not speaking for my employer, although they do rent some of my opinions.
[toc] | [prev] | [next] | [standalone]
| From | blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> |
|---|---|
| Date | 2011-11-18 14:48 +0000 |
| Message-ID | <9in9hvFkg4U2@mid.individual.net> |
| In reply to | #13570 |
In article <slrnjcakol.11i2.usenet-nospam@guild.seebs.net>, Seebs <usenet-nospam@seebs.net> wrote: > On 2011-11-17, blmblm myrealbox.com <blmblm.myrealbox@gmail.com> wrote: > > In article <slrnjc38ub.r7s.usenet-nospam@guild.seebs.net>, > > Seebs <usenet-nospam@seebs.net> wrote: > >> It is very easy for people who have finally been taught that it's not okay > >> to return the address of a local variable to conclude that it's fine to > >> pass the address of a local variable to a function you call. And you're > >> *calling* pthread_create(), see. So that's fine. > > > Well, now *I*'m the one who's confused .... Are you saying > > it's not fine? > > Yes. > > > I suppose if the function you call creates an > > independent thread, and that thread persists longer than the one > > that created it, yes, there could be a problem .... Was that > > your point? > > Yes. > > But it's "fine" according to the simple rule people learn if they don't > really *get* threaded programming. In the absence of threads, passing the > address of a local variable to a function you call is generally safe. > (Not, of course, if that function stashes the pointer for later use...) Good heavens. That way lies madness .... though maybe not, since is it paranoia if they really *are* out to get you? I'd have put myself in the group that claims to "get" threaded programming, but I'll admit I never thought about this particular potential pitfall. Then again, I tend to write the kind of threaded programs in which there's a "master" thread that creates the other threads and doesn't terminate until all the others do, and in that case surely passing addresses of local variables in the master thread to the other threads is okay, no? (At least in the sense that the memory will still be there for the other threads, though if multiple threads have access to the same location, well, there are the usual potential problems with that.) -- B. L. Massingill ObDisclaimer: I don't speak for my employers; they return the favor.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-11-15 14:37 +1300 |
| Message-ID | <9idu23FhikU6@mid.individual.net> |
| In reply to | #13333 |
On 11/15/11 12:14 PM, James Kuyper wrote: > On 11/14/2011 05:29 PM, Ian Collins wrote: > .... >> I think our opinions on what constitutes common sense differ somewhat. > > Probably; I think that the existence of "common sense" is a popular > delusion, based upon people projecting onto others their own > understanding of things. People suffering from that delusion often hold > those others to blame for the failure of that projection to match reality. You're probably right there! >> I see not passing a pointer to something that has gone out of scope in >> the same way as not holding a knife by the blade. In both cases, doing >> the consequences of doing the wrong thing tend to deter a repeat. >> >> Or maybe I've just been doing this stuff for way to long... > > Attempting to dereference a pointer to memory that has already been > deallocated is one of the most common nasty mistakes made by C > programmers. There are many other mistakes that are more common, but > most of them are easier to diagnose than that one. I'm no expert in > multi-threaded code, but it seems to me that the problem can only be > worse if the dynamically allocated memory is shared between threads. Sharing dynamically allocation memory between threads isn't really any mode dangerous than using it in single threaded applications. The same care has to be taken in determining where the memory is released. It goes without saying the problem largely evaporates in C++ with smart pointers. > Several participants on this thread suggested that this was a serious > problem, you've suggested that its trivial. I think that they may be > exaggerating the difficulty, while you may be doing the opposite; I was > hoping to provoke a more detailed discussion that would clarify the > discrepancy. Instead I seem to have only provoked a discussion about my > provocation. I didn't so much suggest it was trivial, only that is was no worse than any other situation with pointers. If you understand threading that is! -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-11-16 10:23 +0200 |
| Message-ID | <87k470bhma.fsf@bazspaz.fatphil.org> |
| In reply to | #13324 |
James Kuyper <jameskuyper@verizon.net> writes: > On 11/14/2011 04:58 PM, Ian Collins wrote: > > On 11/15/11 10:46 AM, James Kuyper wrote: > >> On 11/14/2011 04:15 PM, Ian Collins wrote: > >>> On 11/15/11 08:48 AM, James Kuyper wrote: > >> > >>>> A relevant response would give reasons justifying your treatment of that > >>>> possibility as unimportant. > >>> > >>> Where did I say it was unimportant? > >> > >> You asked "what's the problem?" in the same sentence where you conceded > >> both the existence and relevance of the problem you were asking about. > > > > In the same vein as "as long as you hold the knife by the handle, what's > > the problem?". > > I would interpret a question such as that as one which dismisses the > importance of having to hold the knife by the handle, because it's easy > to arrange to do so. I had assumed you were doing the same: implicitly > asserting that it's trivial to arrange that the address remains valid; By default, addresses remain valid unless you explicitly do something that makes them invalid. Phil -- Unix is simple. It just takes a genius to understand its simplicity -- Dennis Ritchie (1941-2011), Unix Co-Creator
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-11-16 06:53 -0500 |
| Message-ID | <ja087s$oq6$1@dont-email.me> |
| In reply to | #13464 |
On 11/16/2011 03:23 AM, Phil Carmody wrote: > James Kuyper <jameskuyper@verizon.net> writes: >> On 11/14/2011 04:58 PM, Ian Collins wrote: ... >>> In the same vein as "as long as you hold the knife by the handle, what's >>> the problem?". >> >> I would interpret a question such as that as one which dismisses the >> importance of having to hold the knife by the handle, because it's easy >> to arrange to do so. I had assumed you were doing the same: implicitly >> asserting that it's trivial to arrange that the address remains valid; > > By default, addresses remain valid unless you explicitly do something > that makes them invalid. Off-hand I can think of three ways by which previously valid addresses can be come invalid, and three of them are quite explicit: free(), realloc(), and fclose(). However, the addresses of variables with automatic storage duration become invalid as soon as execution of the block in which they are defined ends; that seems pretty implicit to me. YMMV I hope you're not suggesting that the fact that free(), realloc() and fclose() can only occur explicitly somehow makes it trivial to ensure that they have not yet been called for a given pointer? If that were the case, garbage collection wouldn't be as popular an extension as it is. Even in single-threaded code it takes a certain amount of discipline to ensure that a pointer is not used after the memory it points to has been free()d. When possible, I try to make sure that pointers into dynamically allocated memory are stored only in automatic objects whose lifetime ends immediately after the call to free(), rendering it impossible for such problems to occur. However, it's not always possible to impose such restrictions. When I can't do that, I insert code setting the pointer to NULL immediately after the free(). However, to be helpful, that requires that I protect all problematic uses of such a pointer with tests to determine whether it's null. When the expressions p=malloc(), *p=3, x=*p, and free(p) occur in two or more different threads executing asynchronously, it seems to me that it would be all that much harder to ensure that they occur only in the proper order. I'm not saying it's impossible - just that it's harder. Though Ian has assured me that this is not the case, I don't quite see how that could be. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-11-16 11:15 -0500 |
| Message-ID | <4EC3E191.2050006@verizon.net> |
| In reply to | #13469 |
On 11/16/2011 06:53 AM, James Kuyper wrote: ... > Off-hand I can think of three ways by which previously valid addresses Yes, I can count. However, when I decided to add realloc() to the list, I forgot to update that to "four". > can be come invalid, and three of them are quite explicit: free(), > realloc(), and fclose(). > However, the addresses of variables with automatic storage duration > become invalid as soon as execution of the block in which they are > defined ends; that seems pretty implicit to me. YMMV
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-11-16 17:08 +0000 |
| Message-ID | <0.53c25d43b6be0ed2a96e.20111116170813GMT.87aa7wro5e.fsf@bsb.me.uk> |
| In reply to | #13485 |
James Kuyper <jameskuyper@verizon.net> writes: > On 11/16/2011 06:53 AM, James Kuyper wrote: > ... >> Off-hand I can think of three ways by which previously valid addresses > > Yes, I can count. However, when I decided to add realloc() to the list, > I forgot to update that to "four". > >> can be come invalid, and three of them are quite explicit: free(), >> realloc(), and fclose(). >> However, the addresses of variables with automatic storage duration >> become invalid as soon as execution of the block in which they are >> defined ends; that seems pretty implicit to me. YMMV For even greater generality you could replace "variables" with "objects" and you'd be including compound literals that appear inside a function. Oh, reading on I see "defined" which does fit for CLs. "Created" maybe? -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-11-18 15:09 +0200 |
| Message-ID | <877h2xa87f.fsf@bazspaz.fatphil.org> |
| In reply to | #13485 |
James Kuyper <jameskuyper@verizon.net> writes: > On 11/16/2011 06:53 AM, James Kuyper wrote: > ... > > Off-hand I can think of three ways by which previously valid addresses > > Yes, I can count. However, when I decided to add realloc() to the list, > I forgot to update that to "four". It's OK, when in a discussion for mutual edification, I read for meaning, not typos. Phil -- Unix is simple. It just takes a genius to understand its simplicity -- Dennis Ritchie (1941-2011), Unix Co-Creator
[toc] | [prev] | [next] | [standalone]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-11-18 14:24 +0200 |
| Message-ID | <87fwhlaaaf.fsf@bazspaz.fatphil.org> |
| In reply to | #13469 |
James Kuyper <jameskuyper@verizon.net> writes: > On 11/16/2011 03:23 AM, Phil Carmody wrote: > > James Kuyper <jameskuyper@verizon.net> writes: > >> On 11/14/2011 04:58 PM, Ian Collins wrote: > ... > >>> In the same vein as "as long as you hold the knife by the handle, what's > >>> the problem?". > >> > >> I would interpret a question such as that as one which dismisses the > >> importance of having to hold the knife by the handle, because it's easy > >> to arrange to do so. I had assumed you were doing the same: implicitly > >> asserting that it's trivial to arrange that the address remains valid; > > > > By default, addresses remain valid unless you explicitly do something > > that makes them invalid. > > Off-hand I can think of three ways by which previously valid addresses > can be come invalid, and three of them are quite explicit: free(), > realloc(), and fclose(). > However, the addresses of variables with automatic storage duration > become invalid as soon as execution of the block in which they are > defined ends; that seems pretty implicit to me. YMMV I was considering the ending of a scope to be quite explicit. > I hope you're not suggesting that the fact that free(), realloc() and > fclose() can only occur explicitly somehow makes it trivial to ensure > that they have not yet been called for a given pointer? If that were the > case, garbage collection wouldn't be as popular an extension as it is. > Even in single-threaded code it takes a certain amount of discipline to > ensure that a pointer is not used after the memory it points to has been > free()d. That's the fallacy of the hasty generalisation. Whilst /in general/ it's hard to ensure all pointers are treated safely, that doesn't mean for every single pointer it's hard. > When possible, I try to make sure that pointers into dynamically > allocated memory are stored only in automatic objects whose lifetime > ends immediately after the call to free(), rendering it impossible for > such problems to occur. However, it's not always possible to impose such > restrictions. When I can't do that, I insert code setting the pointer to > NULL immediately after the free(). However, to be helpful, that requires > that I protect all problematic uses of such a pointer with tests to > determine whether it's null. That started off sounding like good defensive programming, but as the issue in question was having multiple pointers to the same block of memory, resetting and checking the pointer is not a solution. > When the expressions p=malloc(), *p=3, x=*p, and free(p) occur in two or > more different threads executing asynchronously, it seems to me that it > would be all that much harder to ensure that they occur only in the > proper order. I'm not saying it's impossible - just that it's harder. > Though Ian has assured me that this is not the case, I don't quite see > how that could be. If the creator is tasked with freeing the memory, then clearly some synchronisation is required. However, it the thread is tasked with the free, then none is required (and the creator may defensively NULL the pointer it no longer may assume is valid). Phil -- Unix is simple. It just takes a genius to understand its simplicity -- Dennis Ritchie (1941-2011), Unix Co-Creator
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-11-18 10:08 -0500 |
| Message-ID | <4EC674D1.3090707@verizon.net> |
| In reply to | #13586 |
On 11/18/2011 07:24 AM, Phil Carmody wrote: > James Kuyper <jameskuyper@verizon.net> writes: ... >> I hope you're not suggesting that the fact that free(), realloc() and >> fclose() can only occur explicitly somehow makes it trivial to ensure >> that they have not yet been called for a given pointer? If that were the >> case, garbage collection wouldn't be as popular an extension as it is. >> Even in single-threaded code it takes a certain amount of discipline to >> ensure that a pointer is not used after the memory it points to has been >> free()d. > > That's the fallacy of the hasty generalisation. Whilst /in general/ it's > hard to ensure all pointers are treated safely, that doesn't mean for every > single pointer it's hard. I never meant to suggest that it's always hard. The origin of this discussion was a general comment that "Pass-by-reference and threads aren't known to play well" - I don't think it would appropriate to interpret a comment so casually worded, as having been meant in an absolute sense. That comment, in turn, was in response to proposals to solve Quentin's problem by dynamically allocating memory to store the file descriptor in. I don't think Quentin's description of the problem was ever sufficiently specific to allow us to conclude that this would have been an easy solution. >> When possible, I try to make sure that pointers into dynamically >> allocated memory are stored only in automatic objects whose lifetime >> ends immediately after the call to free(), rendering it impossible for >> such problems to occur. However, it's not always possible to impose such >> restrictions. When I can't do that, I insert code setting the pointer to >> NULL immediately after the free(). However, to be helpful, that requires >> that I protect all problematic uses of such a pointer with tests to >> determine whether it's null. > > That started off sounding like good defensive programming, but as the > issue in question was having multiple pointers to the same block of > memory, resetting and checking the pointer is not a solution. I don't think multiple pointers to the same block of memory has ever been brought up in the messages leading to this one. You are, of course, perfectly correct that the solution is not sufficient for that case. Options include nulling all of the saved pointers, or designating one particular pointer (most reasonably, the one that free() will be applied to) which must be checked to make sure it's not null before using any of the others. There's other, more complicated solutions possible, depending upon the nature of the problem. The key point is that, one way or another, if a stored pointer has a possibility of being de-referenced when invalid, something must be done to remove that possibility. That constrains designs in ways that make them harder to write, harder to read, possibly less efficient, and more prone to error. >> When the expressions p=malloc(), *p=3, x=*p, and free(p) occur in two or >> more different threads executing asynchronously, it seems to me that it >> would be all that much harder to ensure that they occur only in the >> proper order. I'm not saying it's impossible - just that it's harder. >> Though Ian has assured me that this is not the case, I don't quite see >> how that could be. > > If the creator is tasked with freeing the memory, then clearly some > synchronisation is required. However, it the thread is tasked with the > free, then none is required (and the creator may defensively NULL the > pointer it no longer may assume is valid). I was talking about pointers to memory that are shared between threads; you're talking about the simpler case where a pointer to dynamically allocated memory is passed between threads, but is never in use by two of them at the same time. That's certainly a safer approach, but I doubt that it's always acceptable to impose such constraints on how the pointer is used.
[toc] | [prev] | [next] | [standalone]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-11-18 17:52 +0200 |
| Message-ID | <87k46x8m1y.fsf@bazspaz.fatphil.org> |
| In reply to | #13596 |
James Kuyper <jameskuyper@verizon.net> writes: > On 11/18/2011 07:24 AM, Phil Carmody wrote: > > James Kuyper <jameskuyper@verizon.net> writes: > ... > >> When the expressions p=malloc(), *p=3, x=*p, and free(p) occur in two or > >> more different threads executing asynchronously, it seems to me that it > >> would be all that much harder to ensure that they occur only in the > >> proper order. I'm not saying it's impossible - just that it's harder. > >> Though Ian has assured me that this is not the case, I don't quite see > >> how that could be. > > > > If the creator is tasked with freeing the memory, then clearly some > > synchronisation is required. However, it the thread is tasked with the > > free, then none is required (and the creator may defensively NULL the > > pointer it no longer may assume is valid). > > I was talking about pointers to memory that are shared between threads; > you're talking about the simpler case where a pointer to dynamically > allocated memory is passed between threads, but is never in use by two > of them at the same time. That's certainly a safer approach, but I doubt > that it's always acceptable to impose such constraints on how the > pointer is used. There's certainly been some drift in the thread, and I'm quite possibly guilty of blindly steering that. The particular (pthread) scenario is impossible in the C codebase I maintain, but I know that were something equivalent to crop up in a pull request without adequate synchronisation primitives, I'd reject it immediately. I.e. I don't just think it's acceptable, I think it's obligatory in the context I'm familiar with. However, my perspective is admittedly narrow. Phil -- Unix is simple. It just takes a genius to understand its simplicity -- Dennis Ritchie (1941-2011), Unix Co-Creator
[toc] | [prev] | [next] | [standalone]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2011-11-14 15:45 -0700 |
| Message-ID | <1b39dqjpbj.fsf@pfeifferfamily.net> |
| In reply to | #13317 |
Ian Collins <ian-news@hotmail.com> writes: > On 11/15/11 08:48 AM, James Kuyper wrote: >> On 11/14/2011 02:28 PM, Ian Collins wrote: >>> On 11/15/11 08:10 AM, William Ahern wrote: >> .... >>>> Pass-by-reference and threads aren't >>>> known to play well. IMHO the OP had sensible intuition to pass the >>>> descriptor by value. It may not be pretty in C, but neither is threaded >>>> programming. >>> >>> As long as the address is still valid when a thread dereferences it, >>> what's the problem? >> >> The possibility that the address might NOT still be valid at the time of >> use. This has already been pointed out, and is explicitly considered >> (but somehow ignored as unimportant) in your own response. > > I had assumed a competent programmer would be aware of the issue. I > had further assumed a programmer writing threaded applications to be > competent. If either of those assumptions are untrue, the > programmer's foray into threaded programming will be brief and > painful. Painful, anyway :)
[toc] | [prev] | [next] | [standalone]
| From | "christian.bau" <christian.bau@cbau.wanadoo.co.uk> |
|---|---|
| Date | 2011-11-10 15:19 -0800 |
| Message-ID | <8215f761-2d49-4cdb-9a69-d5cd3cbb0bf1@o5g2000yqa.googlegroups.com> |
| In reply to | #13047 |
On Nov 10, 8:21 pm, Quentin Pope <qp19...@hotmail.NOSPAM.com> wrote: > What is the best way to handle this warning: > > warning: cast from pointer to integer of different size On MacOS X 64 bit, an int or unsigned int cast to a pointer will _never_ produce a valid pointer. So the warning is very much justified. Now imagine you wanted to pass a long double. Or a long long on a system with 32 bit pointers. Your approach just cannot work in these cases. The safe thing to do is to allocate some memory with malloc, store whatever you want to pass in the allocated memory, and pass the pointer, so someone else can then safely pick up the data.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2011-11-10 23:41 +0000 |
| Message-ID | <20111110152818.166@kylheku.com> |
| In reply to | #13069 |
On 2011-11-10, christian.bau <christian.bau@cbau.wanadoo.co.uk> wrote: > On Nov 10, 8:21 pm, Quentin Pope <qp19...@hotmail.NOSPAM.com> wrote: >> What is the best way to handle this warning: >> >> warning: cast from pointer to integer of different size > > On MacOS X 64 bit, an int or unsigned int cast to a pointer will > _never_ produce a valid pointer. So the warning is very much > justified. The warning is about a different size, not about never producing a valid pointer. > Now imagine you wanted to pass a long double. Then you'd be writing a different program, requiring a different approach. Conversions between pointer and long double are not even a standard feature of the C language; a diagnostic is required. > Or a long > long on a system with 32 bit pointers. In what situation would you need a POSIX file descriptor to be held in a long long? Descriptor values are allocated into the smallest available position, so if your program is ever to achieve a file descriptor value of N, it must at least momentarily create a situation where there N+1 descriptors simultaneously open. Single Unix Spec Issue 6, on the subject of the open function: ``Upon successful completion, the function shall open the file and return a non-negative integer representing the lowest numbered unused file descriptor. Otherwise, -1 shall be returned and errno set to indicate the error. No files shall be created or modified if the function returns -1.'' > Your approach just cannot work > in these cases. Casting a small long long value to a 32 bit pointer and back to recover that value is something that is /widely/ portable. > The safe thing to do is to allocate some memory with malloc, store > whatever you want to pass in the allocated memory, and pass the > pointer, so someone else can then safely pick up the data. There is nothing unsafe about the conversions when they work. They're only unsafe on some fictitious machine where you get a trap representation, etc. "Less than maximally portable" and "unsafe" are totally different concepts. Getting it running on the weird machine is the porter's responsibility. He hopes to make X dollars by porting the program to a weird platform Y, guessing that he can do so with an investment of Z dollars in an amount of time T and takes his chances accordingly.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-11-10 20:48 -0800 |
| Message-ID | <lnsjlv6z94.fsf@nuthaus.mib.org> |
| In reply to | #13071 |
Kaz Kylheku <kaz@kylheku.com> writes:
> On 2011-11-10, christian.bau <christian.bau@cbau.wanadoo.co.uk> wrote:
>> On Nov 10, 8:21 pm, Quentin Pope <qp19...@hotmail.NOSPAM.com> wrote:
>>> What is the best way to handle this warning:
>>>
>>> warning: cast from pointer to integer of different size
>>
>> On MacOS X 64 bit, an int or unsigned int cast to a pointer will
>> _never_ produce a valid pointer. So the warning is very much
>> justified.
>
> The warning is about a different size, not about never producing
> a valid pointer.
Ok, but casting to a different size could well be a problem *because*
it produces an invalid pointer (among other reasons).
>> Now imagine you wanted to pass a long double.
>
> Then you'd be writing a different program, requiring a different
> approach.
>
> Conversions between pointer and long double are not even a standard feature of
> the C language; a diagnostic is required.
Are you sure about that? What constraint does such a conversion
(which must be written as a cast) violate?
C99 6.5.4 "Cast operators" says that the operand and target type must
both have scalar types (which covers pointers and long double).
6.3.2.3 (pointer conversions) doesn't define the behavior of converting
between pointers and floating-point types.
I believe the behavior of a conversion from long double to void* is
undefined by omission.
(Data point: gcc rejects such a cast with an error message; this is a
valid response to undefined behavior according to the note in 3.4.3).
>> Or a long
>> long on a system with 32 bit pointers.
>
> In what situation would you need a POSIX file descriptor to be held in a long
> long? Descriptor values are allocated into the smallest available position, so
> if your program is ever to achieve a file descriptor value of N, it must at
> least momentarily create a situation where there N+1 descriptors simultaneously
> open.
Obviously that would be in a situation where you're passing something
other than a POSIX file descriptor.
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | "christian.bau" <christian.bau@cbau.wanadoo.co.uk> |
|---|---|
| Date | 2011-11-14 03:39 -0800 |
| Message-ID | <4eeab940-418e-4fd9-9349-007c49b8dca5@j10g2000vbe.googlegroups.com> |
| In reply to | #13071 |
On Nov 10, 11:41 pm, Kaz Kylheku <k...@kylheku.com> wrote: > Casting a small long long value to a 32 bit pointer and back to recover > that value is something that is /widely/ portable. Casting an integer that doesn't contain any address information to a pointer is always a hack. The OP is worried because the compiler gave a warning about the hack. I explained why this warning is a very sensible warning indeed, and there have been various posts explaining how the poster can solve this problem with completely clean and unhacked code. Now an optimizing compiler could easily conclude that producing a data pointer value that is not a null pointer or a pointer to an object or past the last byte of an object is always undefined behavior, and on MacOS X 64 bit and probably on other 64 bit systems casting an int to a pointer will _always_ invoke undefined behavior unless the int has a value of 0, and that therefore the result is always a null pointer. gcc tends to do that kind of optimizations and break "widely portable" undefined behavior.
[toc] | [prev] | [next] | [standalone]
| From | Lauri Alanko <la@iki.fi> |
|---|---|
| Date | 2011-11-14 13:08 +0000 |
| Message-ID | <j9r3t7$n32$1@oravannahka.helsinki.fi> |
| In reply to | #13274 |
In article <4eeab940-418e-4fd9-9349-007c49b8dca5@j10g2000vbe.googlegroups.com>, christian.bau <christian.bau@cbau.wanadoo.co.uk> wrote: > on > MacOS X 64 bit and probably on other 64 bit systems casting an int to > a pointer will _always_ invoke undefined behavior unless the int has a > value of 0, and that therefore the result is always a null pointer. On MacOS X the result may indeed be a null pointer, but, as discussed previously (the thread of <ijo6qc$kql$1@oravannahka.helsinki.fi>), this behavior does not seem to be guaranteed by the standard. Lauri
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-11-14 09:21 -0500 |
| Message-ID | <j9r84f$di1$1@dont-email.me> |
| In reply to | #13278 |
On 11/14/2011 08:08 AM, Lauri Alanko wrote: > In article <4eeab940-418e-4fd9-9349-007c49b8dca5@j10g2000vbe.googlegroups.com>, > christian.bau <christian.bau@cbau.wanadoo.co.uk> wrote: >> on >> MacOS X 64 bit and probably on other 64 bit systems casting an int to >> a pointer will _always_ invoke undefined behavior unless the int has a >> value of 0, and that therefore the result is always a null pointer. > > On MacOS X the result may indeed be a null pointer, but, as discussed > previously (the thread of <ijo6qc$kql$1@oravannahka.helsinki.fi>), > this behavior does not seem to be guaranteed by the standard. It is not. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-11-14 12:54 -0800 |
| Message-ID | <lnfwhq4e85.fsf@nuthaus.mib.org> |
| In reply to | #13274 |
"christian.bau" <christian.bau@cbau.wanadoo.co.uk> writes:
[...]
> Now an optimizing compiler could easily conclude that producing a data
> pointer value that is not a null pointer or a pointer to an object or
> past the last byte of an object is always undefined behavior, and on
> MacOS X 64 bit and probably on other 64 bit systems casting an int to
> a pointer will _always_ invoke undefined behavior unless the int has a
> value of 0, and that therefore the result is always a null pointer.
> gcc tends to do that kind of optimizations and break "widely portable"
> undefined behavior.
This:
void *ptr = 0;
is guaranteed to set ptr to a null pointer value, because the constant
0 is a null pointer constant. This:
int var = 0;
void *ptr = (int*)var;
is not (though it's likely to do so under most implementations).
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [standalone]
Page 3 of 3 — ← Prev page 1 2 [3]
Back to top | Article view | comp.lang.c
csiph-web