October 30, 2012
On Tue, Oct 30, 2012 at 08:55:26PM +0100, Jacob Carlborg wrote:
> On 2012-10-30 18:34, Brad Roberts wrote:
> 
> >I'm all for idealistic views, but neither of those matches reality in any meaningful way.  What I outlined is actually practical.
> 
> Well yes, for an already existing tool. But I see no reason why one wouldn't use this approach when developing a new tool. Lately, all my tools I write are built as libraries and a fairly thin executable that calls the library. Except that one can use the library in other tools it separates and modularize the code, easier to test and so on.
[...]

I have recently come to the conclusion that *all* programs should be written as (potential) libraries with thin executable wrappers. Any other approach will suffer from reusability issues down the road.


T

-- 
One Word to write them all, One Access to find them, One Excel to count them all, And thus to Windows bind them. -- Mike Champion
October 30, 2012
On 10/30/12 2:13 PM, Jesse Phillips wrote:
> On Tuesday, 30 October 2012 at 07:43:41 UTC, Walter Bright wrote:
>> On 10/29/2012 11:08 PM, Daniel Murphy wrote:
>>> void foo();
>>
>> There will be no line information for the above.
>>
>> > void main()
>> > {
>> > foo();
>>
>> For this, yes, but that is not what is being asked for.
>
> Well, personally I think I would enjoy having this line number. The more
> information the better.

Not sure I'm following but essentially if foo() is undefined the most interesting file/line references would be for all calls to foo(). The lines declaring foo() are nice to have but much less interesting.

Andrei
October 30, 2012
On Tue, 30 Oct 2012, Andrei Alexandrescu wrote:

> On 10/30/12 2:13 PM, Jesse Phillips wrote:
> > On Tuesday, 30 October 2012 at 07:43:41 UTC, Walter Bright wrote:
> > > On 10/29/2012 11:08 PM, Daniel Murphy wrote:
> > > > void foo();
> > > 
> > > There will be no line information for the above.
> > > 
> > > > void main()
> > > > {
> > > > foo();
> > > 
> > > For this, yes, but that is not what is being asked for.
> > 
> > Well, personally I think I would enjoy having this line number. The more information the better.
> 
> Not sure I'm following but essentially if foo() is undefined the most
> interesting file/line references would be for all calls to foo(). The lines
> declaring foo() are nice to have but much less interesting.
> 
> Andrei

I don't think I agree.  The key questions that come to mind from an undefined symbol error at link time are:

1) Why did the compiler believe it would be?  If it didn't think it was a valid usable symbol, it would have already errored at the call site during semantic analysis.

2) what's the fully qualified name of the symbol?  Maybe the compiler is matching a different symbol than expected.  However, if that was the case, either it'd link against the unexpected match successfully, or see also #1.


Having the location of some or all of the call sites might help you find #1, but that's a poor substitute for pointing directly at #1.
October 30, 2012
On 10/30/12 5:07 PM, Brad Roberts wrote:
> On Tue, 30 Oct 2012, Andrei Alexandrescu wrote:
>
>> On 10/30/12 2:13 PM, Jesse Phillips wrote:
>>> On Tuesday, 30 October 2012 at 07:43:41 UTC, Walter Bright wrote:
>>>> On 10/29/2012 11:08 PM, Daniel Murphy wrote:
>>>>> void foo();
>>>>
>>>> There will be no line information for the above.
>>>>
>>>>> void main()
>>>>> {
>>>>> foo();
>>>>
>>>> For this, yes, but that is not what is being asked for.
>>>
>>> Well, personally I think I would enjoy having this line number. The more
>>> information the better.
>>
>> Not sure I'm following but essentially if foo() is undefined the most
>> interesting file/line references would be for all calls to foo(). The lines
>> declaring foo() are nice to have but much less interesting.
>>
>> Andrei
>
> I don't think I agree.  The key questions that come to mind from an
> undefined symbol error at link time are:
>
> 1) Why did the compiler believe it would be?  If it didn't think it was a
> valid usable symbol, it would have already errored at the call site during
> semantic analysis.

Not getting this at all. All I'm saying is that if the compiler says "I can't find that foo() you're asking for", the most interesting piece of information for me is "where did I ask for it?"

> 2) what's the fully qualified name of the symbol?  Maybe the compiler is
> matching a different symbol than expected.  However, if that was the case,
> either it'd link against the unexpected match successfully, or see also
> #1.

That's in the symbol.


Andrei
October 30, 2012
On Tue, 30 Oct 2012, Andrei Alexandrescu wrote:

> On 10/30/12 5:07 PM, Brad Roberts wrote:
> > 1) Why did the compiler believe it would be?  If it didn't think it was a valid usable symbol, it would have already errored at the call site during semantic analysis.
> 
> Not getting this at all. All I'm saying is that if the compiler says "I can't find that foo() you're asking for", the most interesting piece of information for me is "where did I ask for it?"

Ok, so it points to a place in the code where you used it.  You look at that and say, yup, I did indeed use it.  Not surprising.  Now, why doesn't the linker find it?  Why did the compiler believe it existed?

The site of the usage isn't remotely useful for answering either of those questions and those are the ones that form the disconnect between the compiler, who believed it existed and let the code pass to the next stage), and the linker.
October 30, 2012
On 10/30/12 5:40 PM, Brad Roberts wrote:
> On Tue, 30 Oct 2012, Andrei Alexandrescu wrote:
>
>> On 10/30/12 5:07 PM, Brad Roberts wrote:
>>> 1) Why did the compiler believe it would be?  If it didn't think it was a
>>> valid usable symbol, it would have already errored at the call site during
>>> semantic analysis.
>>
>> Not getting this at all. All I'm saying is that if the compiler says "I can't
>> find that foo() you're asking for", the most interesting piece of information
>> for me is "where did I ask for it?"
>
> Ok, so it points to a place in the code where you used it.  You look at
> that and say, yup, I did indeed use it.  Not surprising.

In the presence of overloading, that is most often surprising. And usually it's not "I" who uses it, it's transitively called by some code I write. That's the hardest part.

> Now, why doesn't
> the linker find it?

Because it's declared but not explicitly made part of the project.

> Why did the compiler believe it existed?

Grep takes care of that. Finding the declaration is never a problem.

> The site of the usage isn't remotely useful for answering either of those
> questions and those are the ones that form the disconnect between the
> compiler, who believed it existed and let the code pass to the next
> stage), and the linker.

Non-issue. Grep takes care of that. Finding the cross-references and the overloading part are the hard problems here. This is so clear to me for so many reasons, I am paralyzed by options.


Andrei
October 30, 2012
On 10/30/2012 2:49 PM, Andrei Alexandrescu wrote:
> On 10/30/12 5:40 PM, Brad Roberts wrote:
>> On Tue, 30 Oct 2012, Andrei Alexandrescu wrote:
>>
>>> On 10/30/12 5:07 PM, Brad Roberts wrote:
>>>> 1) Why did the compiler believe it would be?  If it didn't think it was a
>>>> valid usable symbol, it would have already errored at the call site during
>>>> semantic analysis.
>>>
>>> Not getting this at all. All I'm saying is that if the compiler says "I can't
>>> find that foo() you're asking for", the most interesting piece of information
>>> for me is "where did I ask for it?"
>>
>> Ok, so it points to a place in the code where you used it.  You look at
>> that and say, yup, I did indeed use it.  Not surprising.
>
> In the presence of overloading, that is most often surprising. And usually it's
> not "I" who uses it, it's transitively called by some code I write. That's the
> hardest part.
>
>> Now, why doesn't
>> the linker find it?
>
> Because it's declared but not explicitly made part of the project.
>
>> Why did the compiler believe it existed?
>
> Grep takes care of that. Finding the declaration is never a problem.

I find it ironic that you mention grep. Grep is what I suggested in the link to dealing with the issue, but nobody likes that answer.

http://www.digitalmars.com/ctg/OptlinkErrorMessages.html#symbol_undefined


>> The site of the usage isn't remotely useful for answering either of those
>> questions and those are the ones that form the disconnect between the
>> compiler, who believed it existed and let the code pass to the next
>> stage), and the linker.
>
> Non-issue. Grep takes care of that. Finding the cross-references and the
> overloading part are the hard problems here. This is so clear to me for so many
> reasons, I am paralyzed by options.

If you're missing a definition, you need to find the declaration, not the use, because that's where the missing definition needs to go.

And finally, grepping for an un-mangled name doesn't work for overloaded names.

October 30, 2012
On 10/30/12 6:00 PM, Walter Bright wrote:
> I find it ironic that you mention grep. Grep is what I suggested in the
> link to dealing with the issue, but nobody likes that answer.
>
> http://www.digitalmars.com/ctg/OptlinkErrorMessages.html#symbol_undefined

Mangling is the issue here.

>>> The site of the usage isn't remotely useful for answering either of
>>> those
>>> questions and those are the ones that form the disconnect between the
>>> compiler, who believed it existed and let the code pass to the next
>>> stage), and the linker.
>>
>> Non-issue. Grep takes care of that. Finding the cross-references and the
>> overloading part are the hard problems here. This is so clear to me
>> for so many
>> reasons, I am paralyzed by options.
>
> If you're missing a definition, you need to find the declaration, not
> the use, because that's where the missing definition needs to go.
> And finally, grepping for an un-mangled name doesn't work for overloaded
> names.

Upon more thinking, I agree that BOTH declarations and call sites must be clearly pointed in the errors output by the linker. But I'll still point out that the real difficulty is finding the calls, not the declarations. I don't ever remember having a hard time "where is this declared?" Instead, the hard problem has always been "What is the call chain that leads to an undefined symbol?"


Andrei
October 30, 2012
On Tue, Oct 30, 2012 at 06:04:47PM -0400, Andrei Alexandrescu wrote:
> On 10/30/12 6:00 PM, Walter Bright wrote:
[...]
> >If you're missing a definition, you need to find the declaration, not the use, because that's where the missing definition needs to go. And finally, grepping for an un-mangled name doesn't work for overloaded names.
> 
> Upon more thinking, I agree that BOTH declarations and call sites must be clearly pointed in the errors output by the linker. But I'll still point out that the real difficulty is finding the calls, not the declarations. I don't ever remember having a hard time "where is this declared?" Instead, the hard problem has always been "What is the call chain that leads to an undefined symbol?"
[...]

You're forgetting the case where the symbol *is* defined, but you forgot to include it in the list of source files to link. In that case, knowing where the declaration is will tell you which source file you probably forgot to add to the linker command line.


T

-- 
Life would be easier if I had the source code. -- YHL
October 31, 2012
On 2012-10-30 22:49, Andrei Alexandrescu wrote:

> Non-issue. Grep takes care of that. Finding the cross-references and the
> overloading part are the hard problems here. This is so clear to me for
> so many reasons, I am paralyzed by options.

Assuming you have a fairly unique symbols in a quite small project. This where an IDE would be great to have. It could point to all the locations of the actual symbol, not just all text that matches the symbol.

-- 
/Jacob Carlborg