Re: Question w.r.t. `'class Foo' has virtual functions but non-virtual destructor` warning.
Frank Ch. Eigler wrote: Karel Gardas <[EMAIL PROTECTED]> writes: [...] class Foo { public: virtual unsigned short iiop_version() const = 0; }; and when I compile it, GCC emits warning from subject, although this class is really abstract and will never be instantiated. [...] I guess GCC assumes that some instances of a derived class will eventually exist, and will be dealt with via a Foo* abstract pointer. Is it common to never attempt to delete it via that Foo* value (which would require a virtual destructor)? In embedded system work, and I'm sure in other circumstances, it is the case that "placement new" is the norm and destructors invoked explicitly (never on an abstract reference,) and the delete operator goes unused. It is also true that embedded systems are resource constrained and that in keeping with the C++ philosophy of not paying for things that are not used, any unused storage overhead created by *requiring* a virtual destructor is ... not good. To make matters more interesting, I *always* compile with -Werror. I am (shamefully) un-aware of any --no-virtual-destructor-warning style flag, that would allow me to compile under these conditions without adding the virtual destructor to all of my many abstract base classes. IOW, it's bad juju in some programming styles/domains, but not in others. back to lurking... -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Questions about trampolines
Robert Dewar wrote: Michael N. Moran wrote: The AVR is a bit more extreme than the Harvard arch you're describing. The AVR has completely separate address spaces for instructions and data. Instruction data space cannot be accessed through a data space pointer. There are separate instructions for accessing instruction and data space. But there must be a way to write stuff into the instruction data space, or how would you load code? So you just have to setup an auxiliary stack in code space. The AVR is an embedded processor, and the instruction space is is Flash *not* RAM. We're not talking about a system that loads programs at run-time. These devices typically have a "large" amount of Flash ROM (32K-68K bytes), and a smaller amount of RAM (512-2K bytes). Don't hold me to these numbers, but you get the idea. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Heads-up: volatile and C++
Jason Merrill wrote: The C++ committee (well, a subgroup represented at this meeting by Hans Boehm) is working on a memory model that supports threaded programs. As someone who uses the C++ language and multi-threading extensively in embedded systems, I have come to the following belief/opinion. The language (C++) *should not* have dependencies upon threading. IMHO, threading is a layer above a systems programming language, and having dependencies upon upper layers is evil. One proposed change is to the semantics of volatile. Since IANALL, but I believe (as obviously you do) that changing the semantics of volatile should be under-taken with great care. I'm not familiar with ia64 barrier instructions, but I *am* familiar with PowerPC barrier and synchronization instructions (eieio, sync, isync, etc.), and I would question the practice of automatically generating these as side effect of a variable being declared as volatile, if for no other reason than the possible presence of code that is unnecessary in some (perhaps most) circumstances. If the committee believes that the language needs support for barriers, then I believe it would be better to use a different approach. For example: o barrier keyword(s) o barrier qualifier(s) While I'm on my soap-box ... I would like to see some sort of alignment qualifiers added to the C++ language for those of us that need to deal with directly with page/cache alignment (for both types and objects.) -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Heads-up: volatile and C++
Paul Koning wrote: "Michael" == Michael N Moran <[EMAIL PROTECTED]> writes: Michael> Jason Merrill wrote: >> One proposed change is to the semantics of volatile. Michael> I'm not familiar with ia64 barrier instructions, but I *am* Michael> familiar with PowerPC barrier and synchronization Michael> instructions (eieio, sync, isync, etc.), and I would Michael> question the practice of automatically generating these as Michael> side effect of a variable being declared as volatile, if for Michael> no other reason than the possible presence of code that is Michael> unnecessary in some (perhaps most) circumstances. I don't understand that. My reaction is just the opposite -- obeying the defined semantics of "volatile" (the present ones as well as the proposed ones) requires the insertion of barrier or synchronizing instructions on platforms where those are needed to ensure ordered global visibility. Again, I understand the need for ordering/synchronization, I simply do not believe that volatile should be overloaded to include these semantics. Part of my point is that there are existing uses of volatile which whose performance would suffer should ordering and/or synchronization instructions be added around each access. For example, device drivers that perform memory mapped I/O on memory spaces which are "guarded" and thus need no additional ordering/synchronization instructions. Or are you talking about a system (such as the BCM1250 MIPS processor) which implements coherency across most, but not all, of the system blocks? In that case, yes, when you are using "volatile" to communicate within the coherence domain, barrier instructions are not needed -- but if you use "volatile" to communicate *outside* the coherence domain, they are. If you assume most cases are in the first set, then you'd want the compiler not to supply barriers, you'd handcode them instead using "asm" or builtins. Conversely, if you assume that most cases are in the second set, then your code will be more reliable and only slightly slower if the compiler supplies the barriers. Again, remember that there is *much* existing code that expects the current implementation of volatile semantics. For new code, the addition of a new qualifier specifically geared toward this purpose would protect the current code base and allow for a more precise specification of architectural intent. Clearly, I come from the camp that appreciates fine grained control. I don't like the idea of paying for features I don't need/use. IMHO, this concept is *very* important in systems programming languages. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Heads-up: volatile and C++
Jason Merrill wrote: On Thu, 14 Apr 2005 10:12:37 -0400, "Michael N. Moran" <[EMAIL PROTECTED]> wrote: Jason Merrill wrote: The C++ committee (well, a subgroup represented at this meeting by Hans Boehm) is working on a memory model that supports threaded programs. As someone who uses the C++ language and multi-threading extensively in embedded systems, I have come to the following belief/opinion. The language (C++) *should not* have dependencies upon threading. IMHO, threading is a layer above a systems programming language, and having dependencies upon upper layers is evil. But the memory model for the language must provide semantics that make it possible for threaded programs to be written. Currently, if you want to write a portable pthreads program you need to use a mutex around all uses of shared memory, because they are the only way to guarantee sequential memory ordering. The volatile proposal provides a lighter-weight way to write portable code with explicit memory ordering. You need this for lockless algorithms to work. I am not arguing against such a language capability, I am only arguing against overloading volatile to achieve the goal. Thus, the other suggestions. It seems to me that the current specification of volatile already requires an lwsync around volatile reads and writes, to guarantee that all previous stores have been completed and later ones have not started. I can see how you could arrive at this point-of-view if you accept the view that the C++ language is responsible for understanding multi-threading. However, in the absence of that responsibility, there is no reason for the compiler to perform this function. I prefer requiring the programmer to be explicit, and understand the environment for which he writes. In the spirit of C++, I do not want to pay overhead for features that I do not need or use. And, as an embedded systems programmer, I need and use volatile frequently. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Heads-up: volatile and C++
Jason Merrill wrote: On Thu, 14 Apr 2005 17:11:58 +0100, Nathan Sidwell <[EMAIL PROTECTED]> wrote: ... though I suppose you could argue that they aren't required to be visible outside the current thread. This is my interpretation since (to my knowledge) the C++ language does not generally address threading. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Heads-up: volatile and C++
Jason Merrill wrote: The device driver case seems like a more plausible objection to me, but I'd like to see an example there, too. Though not widely used, download the OSCL and grep for volatile. http://mnmoran.org/oscl-v1.1.tgz There are many device drivers in this tar-ball, mostly related to the MPC860 PowerPC . -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Heads-up: volatile and C++
Jason Merrill wrote: On Thu, 14 Apr 2005 15:26:32 -0400, "Michael N. Moran" <[EMAIL PROTECTED]> wrote: For example, device drivers that perform memory mapped I/O on memory spaces which are "guarded" and thus need no additional ordering/synchronization instructions. You mentioned PowerPC in a previous post; while device memory doesn't need as much explicit ordering as cached memory, http://www-128.ibm.com/developerworks/eserver/articles/powerpc.html says All these rules don't prevent stores to device memory from being issued out of program order with respect to loads from device memory, or vice versa. Instead, the memory-barrier instructions, eieio and sync, must be used when out of order operations could yield incorrect results. you need an eieio between loads and stores, or between two loads, to ensure proper ordering. Yes, the proposed volatile semantics are more than you need. But you do need something. This is not true regarding access to pages of memory marked "guarded" (e.g.. memory mapped I/O.) Such pages ensure that access are not re-ordered by the processor. See the table under "Memory barrier instructions" That said, perhaps the current volatile semantics are a useful primitive for building on with more specific explicit ordering, but that's not clear to me. I'm very much in favor of fine grained synchronization primitives in the compiler, but not of changes to volatile semantics. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Heads-up: volatile and C++
Gabriel Dos Reis wrote: Marcin Dalecki <[EMAIL PROTECTED]> writes: | Templates are a no-go for a well known and well defined subset for C++ | for embedded programming known commonly as well embedded C++. You'd be surprised to learn that embedded systems people do use templates for various things -- among which, maybe the most "paradoxical" is to avoid code bloat. Embedded C++ was a mistake, alas a mistake that seems to last. Just in case there is any voting going on here ... agreed :) -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Heads-up: volatile and C++
Paul Schlie wrote: Michael N. Moran wrote: I'm very much in favor of fine grained synchronization primitives in the compiler, but not of changes to volatile semantics. I wonder if it would be sufficient (if not preferable) to only extend (modify) the semantics for heap/stack and const volatile variables, as enforcing existing volatile semantics for such variables are at best of questionable existing value. i.e.: volatile vv;// volatile sync primitive, w/normal access semantics. volatile const vc; // universal sync primitive, w/normal access semantics. volatile *vp = ; // a true volatile reference. vv; // volatile sync, all pending volatile transactions logically emitted // into the code, but not hard physically synchronized via a HW sync. vc; // universal sync, all pending transactions hard physically sync'ed. *vp = ; // volatile access semantics enforced, with ordering // warranted between equivalent references, but not // otherwise (unless synchronized by referencing a // declared or (cast) volatile sync variable). (with the exception of new sync semantics, non-reference volatile variables do not need to have volatile access semantics, as it would seem to serve no useful purpose for stack/heap allocated variables, and should be allowed to be optimized always just as for any other allocated variable; although their sync, semantic actions must be preserved, thereby may still be used as synchronized value semaphores, etc, or as simply sync's when no access would otherwise be required; and/or allow regular variables to be cast as (volatile), thereby enabling a arbitrary expression to insert a sync, i.e.: (volatile)x = y, or x = (const volatile)y; forcing a specified sync prior to, or after the assignment?) I'm not certain I understand what you are proposing, other than there being some difference connection between how objects are declared (their scope) and the semantics attached with uses of the object. What happens to volatile pointers/references passed through functions? Which "semantic" would be emitted by the compiler when these are dereferenced? Even without a thorough understanding, on the surface, this seems ... unintuitive. Where the above is just expressed as a loose possible alternative to strictly enforcing ordering between all volatile or otherwise transactions without having to necessarily introduce another keyword, for good or bad. I guess that the reason adding new keywords is a problem is its interaction with existing C++ code? Sorry, I'm not an expert. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Null pointer check elimination
Joe Buck wrote: On Sat, Nov 12, 2005 at 04:01:07PM -0500, Andrew Pinski wrote: Was there an example of: int f(int &); int g(void) { int *a = 0; return f(*a); } Yes this would be undefined code but so what. In a case like this, gcc could emit an error (since we can already detect that a reference is always initialized to a null pointer). If it did so, I can almost guarantee that some free software package will be flagged (I recall writing such code myself 10+ years ago, before I knew better), but it still might be a good thing. Of course, it's not hard to hide the fact that a reference is null from the compiler, and the compiler might then do optimizations based on the assumption that the argument to f is a non-null reference. That would be valid according to the standard. Excuse me. IANALL nor am I a compiler expert but ... what kind of optimization might be done with the information that a reference *should* never be null? Especially within the server code (the implementation of "int f(int& a)" in this case.) Perhaps incorrectly, but I tend to use a (C++) reference when I require the caller/client to supply a non-null "pointer" to a single object (as opposed to an array of objects.) Client code is free to dereference a pointer to an object (perhaps allocated in the heap) and invoke the operation. And what is the meaning of code that does this: int foo(int& a) { int*b = &a; if(b ==0) { a(); } else { b(); } } Not that this example makes any sense, nor would I intentionally code this way ... but... Is function a() invoked? Is function b() invoked? Or (most likely) am I just one of those people that hasn't groked the subtleties of the C++ standard despite having used it for more years than I care to remember ;-) -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Null pointer check elimination
Joe Buck wrote: On Mon, Nov 14, 2005 at 01:43:38PM -0500, Michael N. Moran wrote: Excuse me. IANALL nor am I a compiler expert but ... what kind of optimization might be done with the information that a reference *should* never be null? Especially within the server code (the implementation of "int f(int& a)" in this case.) There are several examples. One is converting from a derived class to a base class when there is multiple inheritance. An offset must be subtracted, unless it is a null pointer. Why does it matter if the pointer is null? It is an error in the program if it uses the result, but the same is true for using null pointers. Do we try to do something if the reference is to another invalid address (e.g. 0x01)? Do we want to hide the error by not crashing? Why not just do the math and keep running? This seems like a run-time check that is not a part of the C/C++ language as I understand it. Another is the "delete" operator. It must first check that the argument is null; it only calls the underlying memory allocator if it is not. I have a similar problem with this. Neither of these appear to be optimizations. As far as I know there is nothing that requires an implementation to do this kind of run-time checking even if we are dealing with pointers instead of references. Of course ... I *could* be wrong ;-) Perhaps I am not understanding (most likely), but I am still interested... Sorry if I'm just way off course. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Null pointer check elimination
Gabriel Dos Reis wrote: "Michael N. Moran" <[EMAIL PROTECTED]> writes: | And what is the meaning of code that does this: | | int foo(int& a) | { | int*b = &a; | | if(b ==0) | { | a(); | } | else | { | b(); | } According to the standard, the compiler can assume that the test is always false, therefore rewrite the if-else as an unconditional call to b(). GCC already does some null-pointer check deleting. Wow. I'm sure there is sound reasoning for this ... but I can't understand what that might be given a client module could intentionally (if ill-adviseadly) simply invoke the function: void bar() { int* z=0; foo(*z); } In short this is "surprising" to clearly under-informed me. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Null pointer check elimination
Joe Buck wrote: On Mon, Nov 14, 2005 at 01:43:38PM -0500, Michael N. Moran wrote: Excuse me. IANALL nor am I a compiler expert but ... what kind of optimization might be done with the information that a reference *should* never be null? Especially within the server code (the implementation of "int f(int& a)" in this case.) There are several examples. One is converting from a derived class to a base class when there is multiple inheritance. An offset must be subtracted, unless it is a null pointer. Another is the "delete" operator. It must first check that the argument is null; it only calls the underlying memory allocator if it is not. It's also surprising to me that the delete operator can be used on a reference when the new operator returns a pointer and the only way to get that (possibly null) pointer to be used as a reference is to dereference it and then apply delete on the pointer formed by the address-of operator on the resulting reference void buzz(Abc& b) { delete &b; } void baz() { Abc& a = * new Abc(); buzz(a); } -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Null pointer check elimination
Gabriel Dos Reis wrote: "Michael N. Moran" <[EMAIL PROTECTED]> writes: [...] | Do we want to hide the error by not crashing? Why not just do the | math and keep running? This seems like a run-time check that | is not a part of the C/C++ language as I understand it. defined by which standards? At this point, I am entirely out of my league. As I said in my initial post, IANALL, I am simply one who has lurked on this list for years because of my interest in GCC as it applies to C/C++ . I freely admit to my ignorance on issues of the standards, but this behavior is surprising to me. You guys do a great job, and I depend on your compiler. I *want* GCC to be standards compliant, so I am not complaining. Its just that given the systems programming roots of C/C++ and the "you don't pay for what you don't use" and the "least surprise" maxims, I feel a bit confused. Sorry, I'll shut-up or go complain to the standards bodies ... yikes! ;-) -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Null pointer check elimination
Gabriel Dos Reis wrote: "Michael N. Moran" <[EMAIL PROTECTED]> writes: | void buzz(Abc& b) | { | delete &b; | } | | void baz() | { | Abc& a = * new Abc(); If no memory is available, the new-expression throws an exception so the dereference never occurs. Check out C++ manuals. As a systems programmer (embedded), I frequently use "-fno-exceptions". What behavior can I expect under these circumstances? -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Null pointer check elimination
Gabriel Dos Reis wrote: "Michael N. Moran" <[EMAIL PROTECTED]> writes: | Wow. I'm sure there is sound reasoning for this ... but I can't | understand what that might be given a client module could intentionally | (if ill-adviseadly) simply invoke the function: then it gets what it deserves. Check out GCC manual for null-pointer check. From info gcc: `-fdelete-null-pointer-checks' Use global dataflow analysis to identify and eliminate useless checks for null pointers. The compiler assumes that dereferencing a null pointer would have halted the program. If a pointer is checked after it has already been dereferenced, it cannot be null. The second sentence makes me question the difference between an actual dereferencing operation and the use of a dereferencing operator used to convert a pointer to a C++ reference. Clearly (to me anyway ;-) the conversion case does not actually cause an access to the object. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Null pointer check elimination
Gabriel Dos Reis wrote: "Michael N. Moran" <[EMAIL PROTECTED]> writes: | Gabriel Dos Reis wrote: | > "Michael N. Moran" <[EMAIL PROTECTED]> writes: | > | void buzz(Abc& b) | > | { | > | delete &b; | > | } | > | | void baz() | > | { | > | Abc& a = * new Abc(); | > If no memory is available, the new-expression throws an exception so | > the dereference never occurs. Check out C++ manuals. | | As a systems programmer (embedded), I frequently use "-fno-exceptions". | What behavior can I expect under these circumstances? You have to manually check the return value of new. There is no substitute for that. At least, if you don't want to invoke that kind of undefined behaviour. Fine. I must relent and remain surprised. Going back to the root of this discussion, however: | Joe Buck wrote: | > Another is the "delete" operator. It must first check that the | > argument is null; it only calls the underlying memory allocator | > if it is not. I would simply expect the underlying memory allocator to be invoked regardless of whether or not a pointer was null, but honestly, in my line of work I rarely use the delete operator. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Null pointer check elimination
Gabriel Dos Reis wrote: "Michael N. Moran" <[EMAIL PROTECTED]> writes: | From info gcc: | | `-fdelete-null-pointer-checks' | Use global dataflow analysis to identify and eliminate useless | checks for null pointers. The compiler assumes that dereferencing | a null pointer would have halted the program. If a pointer is | checked after it has already been dereferenced, it cannot be null. | | The second sentence makes me question the difference between an | actual dereferencing operation and the use of a dereferencing | operator used to convert a pointer to a C++ reference. Clearly | (to me anyway ;-) the conversion case does not actually cause | an access to the object. It is not a conversion. It is a dereference operation that is defined only for non-null operand. No ifs, no buts. I'm in over my head, but ... (oops there's a but ;-) here goes: void bar(int& a); void foo(int* a) { // dereference: conversion to reference // Since there is not necessarily any object access, // thus no assured SEGFAULT. bar(*a); // dereference: access to object // If a is null, then SEGFAULT *a = 0; } Sorry to drag this out. I'm sure its just one of those "that's the way the language is defined Moran get over it" issues, but (no ifs) ... -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Null pointer check elimination
Gabriel Dos Reis wrote: "Michael N. Moran" <[EMAIL PROTECTED]> writes: | void bar(int& a); | | void foo(int* a) | { | // dereference: conversion to reference | // Since there is not necessarily any object access, | // thus no assured SEGFAULT. | bar(*a); SEGFAULT is not a behaviour defined by the language. Even *I* know that, in spite of my lack of legal expertise. It is *just* one form of undefined behaviour. Are you saying that this portion of the code *will* invoke undefined behavior even if the pointer "a" is valid? Notice this example has nothing to do with null pointers. It is a demonstration of the two kinds of dereferences that I identified. Perhaps the problem is that I am assuming the same object code generated by this function is used for all cases (e.g. null or valid values of "a",) and that assumption falls apart in the presence of optimizations such as inlining and inter procedural optimizations. If you execute that function, it might reformat your harddrive and that woud be fine -- though I know of no compiler that does that on purpose. But, the point is that your program in erring in the outer space. | // dereference: access to object | // If a is null, then SEGFAULT | *a = 0; Again, that may or may not happen. I understand that specifically a SEGFAULT may not happen, but according to the excerpt from the GCC info page above, "The compiler assumes that dereferencing a null pointer would have halted the program." In the first case, the result of the dereferencing *seems* to be an address of the object in the form of a reference, whereas the second case *seems* to clearly modify the object (assuming the object is in memory ... whatever that means in standardise). FWIW, I appreciate your help, and realize that this is not the forum for this kind of discussion. I apparently need to get educated . Thank you for your patience. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
Re: Is there any reason to use vfork() ?
On 05/13/2014 10:59 AM, niXman wrote: pinskia 2014-05-13 18:47: Can you share more information about this env. This is specially built distributive used for micro-pc. It might be a bug not in gcc. I'm sure that the bug not in the GCC. After I wrote to this ML I made sure that freezes any program using 'vfork()'. I'll deal with it ... I just wanted to understand the reasons to use 'vfork()' instead of 'fork()'. I cannot speak for GCC, but I work with embedded Linux systems and we use vfork() to reduce the memory footprint of child processes. When a process is created with fork() it's memory footprint is the same as the parent process (copied page tables). The same is not true with vfork(). This is particularly important in the embedded systems space with limited RAM. Consider the system RAM requirements for a parent process with a large RAM footprint that needs to spawn a child process with an otherwise much smaller RAM footprint. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144http://mnmoran.org The Beatles were wrong: 1 & 1 & 1 is 1
Re: obvious race condition in darwin/netbsd __enable_execute_stack due to caching pagesize/mask
Andrew Thomas Pinski wrote: On Aug 27, 2008, at 0:27, Jay <[EMAIL PROTECTED]> wrote: size = getpagesize(); \ mask = ~((long) size - 1); Or even better store size after the store to mask. That is: int tmp = getpagesize(); *(volatile*)&mask = ~((long)tmp - 1); *(volatile*)&size = tmp; Does this work on machines that support out-of-order execution? For example, shouldn't there be the equivalent of a powerpc eieio to ensure that the stores *happen* in order? I'm assuming, of course, that Darwin runs on different processor architectures.