Re: Variable scope debug info

2007-04-05 Thread Brian Ellis

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

2007-04-06 Thread Brian Ellis
> 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

2007-04-11 Thread Brian Ellis
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?

2009-03-24 Thread Brian Ellis

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;
}