Re: Variable scope debug info
Now if there were actual function calls in the initialization, and no records were emitted, I would consider that to be a problem (haven't tested this at the moment though), however, static initializers like that could easily be skipped as a feature in the interest of saving space. Example : int i = 0; int j = 2; int n = CalculateSomething( j, &i ); int k = 3; I would expect debug records for the initialization of 'n' to be emitted and a break point to properly work on that line... all others I could completely care less for. Heck, if the scope for k (being a primitive type that is initialized with a compile-time constant value) were started before n, i wouldn't even consider that to be a bug... I would consider it a marvel of intelligence in the compiler. - Brian - Original Message From: Joe Buck <[EMAIL PROTECTED]> To: Rob Quill <[EMAIL PROTECTED]> Cc: GCC Development Sent: Thursday, April 5, 2007 12:32:04 PM Subject: Re: Variable scope debug info On Thu, Apr 05, 2007 at 02:37:06PM +0100, Rob Quill wrote: > My problem is thus: When using GDB do debug the follow bit of code: > > int i = 0; > int j = 2; > int k = 3; > > If I set a breakpoint at the 3rd line, before int k = 3; has been > executed, and check if k is in scope, I find that it is, when, of > course, it shouldn't be. I emailed the GDB mailing list about this and > was informed that the problem arose because GCC does not emmit and GDB > cannot handle the DW_AT_start_scope attribute (DWARF 3 standard, page > 61, item 11). If adding scope attributes every time more than one variable is declared adds to the already immense bulk of C++ debugging information, I'd prefer to live with the bug myself. Food fight? Enjoy some healthy debate in the Yahoo! Answers Food & Drink Q&A. http://answers.yahoo.com/dir/?link=list&sid=396545367
Re: Variable scope debug info
> On 05/04/07, Brian Ellis <[EMAIL PROTECTED]> wrote: > > > > Now if there were actual function calls in the initialization, and no > > records were emitted, I would consider that to be a problem (haven't tested > > this at the moment though), however, static initializers like that could > > easily be skipped as a feature in the interest of saving space. > > > > Example : > > int i = 0; > > int j = 2; > > int n = CalculateSomething( j, &i ); > > int k = 3; > > > > I would expect debug records for the initialization of 'n' to be emitted > > and a break point to properly work on that line... all others I could > > completely care less for. > > I don't really understand, because the problem remains that if you > break before int n... and do print n you get a value, whereas you > should get an error saying the variable is not in scope. > > > Heck, if the scope for k (being a primitive type that is initialized with a > > compile-time > > constant value) were started before n, i wouldn't even consider that to be > > a bug... I would > > consider it a marvel of intelligence in the compiler. > > How so? > > Rob In theory, an intelligent compiler might be able to initialize primitives on a stack frame either using a faster bulk-copy mechanism or using a lazy assignment mechanism (actual performance gain between the 2 might differ based on source code). Although such an enhancement would be minor, it is still possible that out of order or amortization could pay off. Some might complain that reordering co-scoped primitives is out of the question (such that i, j, and k are all together with maybe a 4th primitive for a bulk initialization), but if I had to touch any code that depended on the ordering of non-struct or not explicitly scoped variables on the stack... I'd wash my hands with bleach. In fact, on some architectures, reordering commonly used variables can have a drastic impact on internal cache bus usage and cause noteworthy performance differences. As long as dependency hierarchies are honored, out of order initialization and placement are no different than out of order execution. Ensuring that this debug information is emitted might tie the hands of such optimizations. Additionally, a debugger is not an automated process. It is a tool intended to be used by an intelligent agent. At the break point before the initialization of n, I would understand if k were visible and maybe already had the value of 3. I could also understand if n were visible and had either a garbage value or (similar to Micro$hit's debug builds) had a preinitialized value of 0xCDCDCDCD. If the debugger can see a value before it's proper initialization, this is something that the user can easily ignore. ONTOH, if a line of code previous to the declaration could see the variable, then that would be a bug. - Brian Expecting? Get great news right away with email Auto-Check. Try the Yahoo! Mail Beta. http://advision.webevents.yahoo.com/mailbeta/newmail_tools.html
Re: Inclusion in an official release of a new throw-like qualifier
Having not read the entire thread, I risk reiterating an idea that may have already been brought up, but I believe I've got a few thoughts that may be of value... and if somebody's already mentioned them, I hope they take this as a compliment and a vote in their favor. > Otherwise as > you said, it will become necessary to include a number of different > std::... exceptions in the throw specifiers for completeness or to > ignore the fact that they may occur. Which brings up the question is it > allowable to let the program terminate if say a std::bad_alloc exception > is thrown. > > I think the current manual audit process for using exceptions and > knowing exactly what is going on is the biggest killer for using > exceptions properly in C++. That was the initial purpose of creating > this project. I think it might be a good idea for the throw specifier to include all types derived from the specified types as acceptable exceptions, especially so for virtual methods. A implementation of a virtual method in a derived class may decide that the defacto-standard exception (that the base stated it would throw) does not contain enough information to fully describe the error. The derived method could then be free to throw an exception of a type derived from the exception class that the base stated it would throw without violating the throw specifiers that it inherits. Any user of the hierarchy in this example could still catch only the specified exception types and not be at risk of letting one slip by. Additionally, programmers using stl templates and letting their exceptions pass thru could merely claim to throw std::exception (being the parent of all stl exceptions... i hope) and not be considered incomplete. > Yes. I agree completely. My first version of EDoc++ did not include the > concept of suppressions, and it just became infeasible to use. There was > too much information and a lot of it just really was not important to > the average developer. > > Practically every function that included a throw specifier would emit > errors if it used anything from STL as for example std::bad_alloc would > be thrown or something similar. By using an external suppressions file > it is possible to indicate locations where exceptions will not logically > propagate even though the compiler thinks that they will as well as > saying that std::bad_alloc among others are "runtime" exceptions > equivalent to Java and not necessary in the specs. > > Again there are issues involved with maintaining an external > suppressions file as opposed to some form of markup within the source code. > > Suppressions can also be used to say i am only interested in information > for a certain set of functions or to restrict the callgraph that may > have been pessimistically expanded from virtual functions or function > pointer calls, or to add function calls (which is currently necessary > when using plugins) or really to modify the resulting data in any way > imaginable. (The suppressions file is actually a python script that can > manipulate the EDoc++ applications internal data structures) Two ideas come to mind: 1. Offer a class attribute that indicates an exception type that is exempt from throw specification checking (__volatile_exception). This could be applied to exception class like std::bad_alloc or other exceptions that just might fly from anywhere. 2. Offer a function attribute(s) to play the role of suppression specifiers (__suppresses and/or __catches... they do represent slightly different meanings). Both of these ideas introduce a level of danger that should be respected by developers, but so do const_cast and reinterpret_cast. > code compiled with > -fno-exceptions linked with code that allows exceptions, same with C++ > and C code intermixed, templates and vague linkage, differing throws() > specifiers for a functions prototype in different translation units, and > the list of complexities goes on... Anybody who does that deserves what they get (anybody who hires them, however, might not). Perhaps the resulting throw specification could be emitted as discardable records of some sort, and the linker could then be enhanced to rub the offending programmer's nose in it (well... at least the differing throws() scenario). Intermixed C & C++ is just a requirement of real life, and I haven't seen anything about function pointers yet... you just have to take the programmer's word on that one, right? I've recently been in a situation where I had to use reference-counted exception classes that could potentially be delivered to multiple receiving threads, and the IO completion thread that generated them had to bucket them with their respective IO buffers, but never get one thrown to it. Having such a feature would have saved me days of sifting thru the hulking beast of an IO subsystem that this design was deployed into. In other words, I would really like to have a feature like this available. - Br
Re: Should structure with flexible array be allowed to be passed by value?
Pardon my intrusion on this thread, but if I ever coded anything so catastrophically hazardous, I'd want to at least be warned about it... if not slapped on the wrist and told "No No No No NO." Structures with flexible array members must be created dynamically in order to allocate proper space for their contents and should, therefore, always be passed or returned by pointer such as any other dynamic data structure. With higher level languages encapsulating such hazards out of sight, it may appear to less experienced programmers as though passing variable length data structures by value were a legitimate operation. I believe that merits at least a warning, if possible, for such misconceived ideas. The following code, by the way, does not emit any errors or warnings when compiled with gcc version 4.1.2.. I haven't tested with any more recent versions. I do understand that we can't protect everybody from every form of hazardous code, but because this was brought up, I figured something should be said. - Brian Ellis - CODE SNIP - #include #include struct dynamic { int size; int array[]; }; void dont_do_this( struct dynamic wrong_answer ) { printf( "Now showing an array of %d wrong answers.\n", wrong_answer.size ); int x; for( x=0; xsize ); int x; for( x=0; xsize; x++) { printf( "\t%d\n", pRightAnswer->array[x] ); } } int main() { struct dynamic * pBadness = ((struct dynamic *) malloc( sizeof(int) * 3) ); if( pBadness == NULL ) { puts( "Failed to allocate memory.\n" ); return -1; } pBadness->size = 2; pBadness->array[0] = 42; pBadness->array[1] = -42; dont_do_this( *pBadness ); do_it_this_way( pBadness ); return 0; } CODE SNIP - Original Message From: H.J. Lu To: Joseph S. Myers Cc: "g...@gnu.org" ; disc...@x86-64.org Sent: Tuesday, March 24, 2009 11:20:40 AM Subject: Re: Should structure with flexible array be allowed to be passed by value? On Tue, Mar 24, 2009 at 8:16 AM, Joseph S. Myers wrote: > On Tue, 24 Mar 2009, H.J. Lu wrote: > >> Should >> >> struct line { >>int length; >>char contents[0]; >> }; >> >> or >> >> struct line { >>int length; >>char contents[]; >> }; >> >> be allowed to be passed by value? If yes, how do you access the contents >> field? > > I see nothing about passing by value different from structure assignment, > which ignores the flexible array member (see 6.7.2.1 paragraph 22 (in > N1256) for an example stating this). Although argument passing and return > aren't strictly assignments, they generally act in the same way, so such a > structure passed by value or used as a function return value loses the > flexible array members in the process. I suppose an optional warning for > this might be useful. > How should be they passed on x86-64? psABI isn't clear and gcc isn't consistent with char contents[0] vs char contents[]. -- H.J. #include #include struct dynamic { int size; int bad[]; }; int dont_do_this( struct dynamic wrong_answer ) { return wrong_answer.bad[1]; } int main() { struct dynamic * pBadness = ((struct dynamic *) malloc( sizeof(int) + 4) ); if( pBadness == NULL ) { puts( "Failed to allocate memory.\n" ); return -1; } pBadness->bad[0] = 42; int not42 = dont_do_this( *pBadness ); printf( "It let me do something very bad and gave me %d as the answer.\n", not42 ); return 0; } #include #include struct dynamic { int size; int bad[]; }; void dont_do_this( struct dynamic wrong_answer ) { printf( "Now showing an array of %d wrong answers.\n", wrong_answer.size ); int x; for( x=0; xsize ); int x; for( x=0; xsize; x++) { printf( "\t%d\n", pRightAnswer->bad[x] ); } } int main() { struct dynamic * pBadness = ((struct dynamic *) malloc( sizeof(int) * 3) ); if( pBadness == NULL ) { puts( "Failed to allocate memory.\n" ); return -1; } pBadness->size = 2; pBadness->bad[0] = 42; pBadness->bad[1] = -42; dont_do_this( *pBadness ); do_it_this_way( pBadness ); return 0; }