![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Let's take a better example: Every time I want to use std::vector,
> I have to #include <vector> in the source file where I want to do so.
> Is there any advantage to this?
For C++ and templates, yes. Altho (and I know you'll go apeshit over this
comment) C# manages not to need the source code for generics like that.
The problem is, again, that it can be abused. It works great as long as you
put templates and declarations and such in there, and as long as you don't
build entire type systems and programming structures and such via macros[*].
It sucks when someone starts using include files that are order-dependent,
that try to enforce coding conventions, that screw up the syntax of the
language you're coding in, etc. None of which is possible if you're not
including someone else's source code into your own compilation.
> OTOH, is there a huge disadvantage in having
> to include the files other than the trouble of having to write the
> #include lines?
Yes. And I had an entire 50-line post detailing the logical disadvantages of
it. Basically, it discussed the benefits of having every source file
actually generate object code. Perhaps you missed it?
[*] And please think about it for a bit before accusing me of moving the
goalposts to include macros, eh? Try to do the "why would he bring up that
topic" question before just assuming I must be doing it to annoy you or
something.
--
Darren New, San Diego CA, USA (PST)
"How did he die?" "He got shot in the hand."
"That was fatal?"
"He was holding a live grenade at the time."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>>> So essentially you want the compiler to know what to compile without
>>> you specifying what to compile.
>
>> Nope. I specified that you want to compile "main".
>
> If your program consists of one single file named "main", then it could
> work.
But it doesn't. And in practice, in C, it almost never does. Yet in many
other languages, it does.
> Don't forget the context. You were talking about 'make' requiring overly
> complicated steps in order to automatically track the dependencies of
> include files in C programs, and how you don't like that.
Correct. In part, because you (for example) already have to know where all
the C header files are in order to generate the dependencies to start with.
> Then, suddenly,
> you come up with a "it's impossible to track dependencies by looking at
> the source code only" argument.
That is correct also. But the two are related. If you don't see how they're
related, then I'm sorry, but you apparently have less experience with really
crappy C code than I do.
> It was clear from the context that you
> were talking about C in particular, as if the same (quite trivial) problem
> didn't happen in more "advanced" languages.
And, generally, it doesn't. Really. It just doesn't cause the same sort of
problems. I've never invoked a Java class where I needed to know what order
to put #include headers in to make it compile.
> So what's the point?
That you're a master troll? That you're ignoring everything I'm saying that
conflicts with your view that it just isn't a problem?
--
Darren New, San Diego CA, USA (PST)
"How did he die?" "He got shot in the hand."
"That was fatal?"
"He was holding a live grenade at the time."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Let's take a better example: Every time I want to use std::vector,
> I have to #include <vector> in the source file where I want to do so.
Or, to phrase it differently:
vector.hpp is a standard file from the standard library. Why the hell are
you compiling it, over and over, every time you compile your program?
Doesn't it strike you as a bit odd that standard libraries that come with
the compiler still get compiled on your CPU over and over?
--
Darren New, San Diego CA, USA (PST)
"How did he die?" "He got shot in the hand."
"That was fatal?"
"He was holding a live grenade at the time."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New wrote:
> That you're a master troll? That you're ignoring everything I'm saying
> that conflicts with your view that it just isn't a problem?
I'm sorry. There was a possibility I didn't consider. Perhaps when you say
"I don't understand", you really mean "I don't understand and I don't care
to have you explain it, either." I can perfectly understand that, if that's
what you meant. I was caught off-guard, because usually "I don't
understand" in a social environment like this doesn't carry an implicit "so
go away about this" trailer. My apologies if I was misinterpreting you in
this way.
--
Darren New, San Diego CA, USA (PST)
"How did he die?" "He got shot in the hand."
"That was fatal?"
"He was holding a live grenade at the time."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 01/02/2011 05:16 PM, Warp wrote:
> Invisible<voi### [at] dev null> wrote:
>> I'm curious to see if turning on optimisations actually makes any
>> noticeable performance difference... I guess I'll find out tomorrow.
>
> Well, it depends on what those programs are actually doing. If they are
> doing some heavy-duty calculations that take seconds or more, then there
> usually is a quite drastic difference between using -O3 and not using it.
How about if the program just calls two or three library functions that
do all the work?
Well anyway, I'll find out in just a minute...
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>>> I'm curious to see if turning on optimisations actually makes any
>>> noticeable performance difference... I guess I'll find out tomorrow.
>>
>> Well, it depends on what those programs are actually doing. If they are
>> doing some heavy-duty calculations that take seconds or more, then there
>> usually is a quite drastic difference between using -O3 and not using it.
>
> How about if the program just calls two or three library functions that
> do all the work?
>
> Well anyway, I'll find out in just a minute...
Conclusion: -O3 = small but measurable performance increase.
(E.g., 27 seconds instead of 30 seconds.)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Invisible <voi### [at] dev null> wrote:
> How about if the program just calls two or three library functions that
> do all the work?
Well, then it shouldn't make much of a difference (because there usually
aren't different versions of libraries depending on your optimization level).
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Warp wrote:
> > The problem is that you didn't know that you can actually implement what
> > Andrew wanted with just a couple of simple and straightforward lines with
> > a makefile
> Of course I knew that. Don't be insulting.
You said, and I quote:
"I don't remember. Do you have to actually list the programs in the makefile
that you want to compile? Is a makefile that compiles 50 programs
necessarily larger than one that compiles 5?"
That tells me that you didn't know about the implicit rules in gnu make
that allow avoiding having to call gcc explicitly (hence saving a significant
amount of writing), or you didn't know about gnu make's support for
wildcards. Probably both.
> > I think it's you who didn't understand. What exactly is this 'make'
> > abuse you are talking about?
> If you've never seen abuse of makefiles, then power to you. I think anyone
> who has worked on an ugly system knows what I'm talking about. Otherwise, go
> look up the "buildroot" system for compiling kernels. I mean, hell,
> buildroot was so makefile-abusive that people capable of working on the
> linux kernel said "screw this, let's throw it away and start over."
So some people have abused make to do something it's not designed to do?
Is that supposed to somehow be a negative point about make, or something?
I already forgot the whole point of this "abuse" thing or why you even
brought it up.
> >> The problem is not that you have to tell the compiler what to
> >> compile. The problem is you have to (in C) compile much more than your own
> >> source code in order to compile your program.
> >
> > You have odd problems. I haven't encountered such a problem as far as
> > I remember.
> Well, good for you. The fact that you've not encountered that problem
> doesn't mean that the problem isn't real.
But it could perfectly well mean that it's not as common as you make it
sound (which, honestly, wouldn't actually surprise me).
Some people write bad code. In some such cases other people need to
decipher that bad code. It probably sucks. However, this problem is not
exclusively limited to C and its variants. (And from what I read at
the daily wtf, higher level languages seem to be much more prominently
represented than lower-level languages like C. Not that this means that
in an absolute scale the problems are not more common in C. However,
it does tell that such problems are also quite common even in higher-level
languages. They are in no way safe from idiotic programmers.)
> > If I install a new library from a OpenSuse repository, I still don't have
> > to care where it's installing it. In fact, I don't even *know* where it's
> > installing them, and I don't need to. They will still work.
> Here you're arguing that someone else has already solved the problem for you.
Yeah, isn't it great? The C/C++ library system isn't so bad as you make
it sound, after all. It works like a charm for me.
> > Can this scheme sometimes cause *more* problems than when dealing with
> > C# on Windows using Microsoft's IDE? Probably. It hasn't bothered me too
> > much so far, though.
> Great. Install compilers for three different versions of Linux for three
> different architectures on the same machine. Make sure that you can use all
> three different versions of boost you need on each of those three compilers.
> Let me know how simple your makefiles are.
> (And you're giving *me* shit about not knowing how makefiles work? Really??)
You are still making all this to be some kind of issue about makefiles.
I don't really understand why.
Perhaps next you'll complain how your car broke and it will cost you an
arm and a leg to repair it, and this, too, has something to do with why
makefiles suck.
> >> You don't understand the word "sources" in that sentence? Reading
> >> comprehension, dear.
> >
> > I don't think I have the sources eg. for libc.so installed in this
> > system, hence I don't have to tell the compiler where they might be.
> Um, yes, you do. You have the sources for some of the openssl libraries
> installed, don't you?
Openssl libraries? I have no idea. Why should I even care?
> > I don't get your point.
> Yes you do.
No, I don't. You are writing about library sources now, and I have no
idea what you are talking about.
> >> The fact that you can automate (in some cases) the copying of dependencies
> >> from one place to another does not mean you're not copying dependencies from
> >> one place to another.
> >
> > And I asked why should I care if it happens automatically behind the
> > scenes.
> And I answered this repeatedly, and you picked nits instead about whether
> invoking the C preprocessor is invoking the compiler or not.
Your "answer" seems to be to endlessly repeat the duplication argument.
You are not telling me why I should care if the dependencies are duplicated,
if the duplication happens automatically.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Warp wrote:
> > Darren New <dne### [at] san rr com> wrote:
> >> Warp wrote:
> >>> How do you resolve this? That's right: You tell the compiler which files
> >>> it needs to compile.
> >
> >> Nope. You tell the compiler which *object* file goes with the appropriate
> >> *source* file.
> >
> > Yeah, huge difference.
> And *this* is exactly why these arguments go on for so long.
> I can't tell whether you're being a truly masterful troll, or whether your
> misplaced egoism has completely blinded you.
> I make a comment. You strawman an argument against it. I point out that
> you're putting words in my mouth. Instead of saying "OK, I was wrong in my
> assertion, I don't see the difference, please explain again why it matters",
> you say "I wasn't wrong, because even tho I was *factually* incorrect, it
> doesn't make any difference, because there couldn't possibly be any
> difference, so I'm really right anyway."
I don't understand what you are talking about.
I said, "you need to tell the compiler which files it should use to
compile the program", and you answer with "no, you tell the compiler
which object file goes with the appropriate source file".
What exactly is the difference here? You are telling the compiler which
source files the program is composed of. What do the object files have
anything to do with this? In fact, you are making it sound *more* complicated
than it needs to be, (Why exactly would I need to specify which object
file goes with what source file? I don't care. Let the compiler figure
those things out. You are in fact making it sound like compiling a C#
program is actually more complicated than compiling a C++ program, if
you need to be explicitly pairing object files with source files.)
Whatever the building process might be, you still need to tell the
compiler in one way or another where your source files are, and that's
the point. If you have two files with the same name, you tell the compiler
which one of them to use. (Your original argument was, after all, what
happens if you have to C files of the same name.) I don't understand what
the "object files" have anything to do with this.
Also, I don't understand what "factually incorrect" thing I have said.
> And you know, for someone who distinguishes "invoking the compiler
> preprocessor" from "invoking the compiler", saying there's no significant
> difference between source code and object code just doesn't ring true.
Somehow it seems that you are talking about something else entirely.
This whole "you tell the compiler which files to compile" argument started
from your example of two C files with the same name. You have now made a
strange jump to some C# object files, and I have no idea why or how it's
related. It seems that you are thinking about something else entirely.
> > Are you saying that it's impossible to have a C# source file with the
> > same name in two different directories and which implement a class with
> > the same name?
> I'm saying that if you do, it doesn't matter, because your compilation isn't
> looking at that source code.
And why not? That's right: Because you only told the compiler to use
*one* of those files, rather than both. It's your decision which one.
You don't seem to get my point here. My point is that your argument about
the two C files with the same name is bogus. In other words, a bad example
and a bad argument.
It's anybody's guess what object files have anything to do with this
whole thing.
> >> Do you really not see the difference between saying "each time I compile
> >> something, I have to pick which source file to compile" and saying "each
> >> time I compile something, I have to pick the right source files that go with
> >> the corresponding libraries of every library I'll eventually link this with"?
> >
> > Not really.
> OK. Then I'm afraid I can't explain it to you.
Well, I just can't see the difference between the two sentences you wrote.
They are saying the same thing.
> > You have to specify which source files the program is
> > composed of.
> It's not my program.
There's a difference between "the" and "my". I wrote "the".
> I've never written a crypto library, nor have I written
> a video codec. But I've compiled the source code for parts of those
> libraries into every C program I've ever written that used them.
So you tell the compiler which source files it should use to compile
the program. So? Isn't that what I'm saying?
> > Your example of the same C file being in two different directories is simply
bogus.
> Why?
Because you tried to use it as some kind of example of why it's "not
possible to figure out dependencies by looking at the source codes only"
and that you need to specify where the compiler has to look for those
sources, and this, apparently, is some kind of "problem" in C.
My answer, which you still don't seem to understand, is that this has
nothing to do with C or any particular language. If you have a file with
the same name in more than one place, you need to tell the compiler which
one it should use. This is obviously true for any language. C isn't somehow
inferior because of this.
Then you start rambling something strange about object files.
> > It has nothing to do with C particularly.
> It is much more common in C than in other languages, I've found. YMMV, but
> that doesn't make me wrong.
You are blaming C for a somewhat common bad practice among C programmers?
If I were to go that path, I would say that C# and ASP are really crappy
languages, judging from what I have seen at thedailwtf. (Of course this
argument would be completely fallacious.)
> >> Indeed, when I use the C# equivalent of stdio (or any other third-party
> >> library), I don't need any source code I didn't write myself, nor do I need
> >> to specify where to find the libraries. I merely say which version of what
> >> implementation I want.
> >
> > And when I write C++, same thing. So what?
> So, when you use boost, you don't need to compile any source code to any
> software you didn't write yourself? Sorry, that's just a lie. I've looked at
> the boost code. It's mostly source code. And you know what? I've worked on
> projects where I've needed two different versions of boost in the same code,
> neither version of which was in the repository. It sucks. It's very
> difficult to get right.
You said, and you quoted it above: "when I use the C# equivalent of stdio",
to which I responded "and when I write C++, same thing". I don't think I
heve the source code for stdio even installed in my linux system.
Also, if talking about template code, in a different subthread I actually
advocated the advantages of having such code in header files, and mentioned
<vector> as an example of this.
I don't understand why you consider it a bad thing that eg. the boost
libraries are mostly in the header files (often because they are fully
templated and cannot be placed in precompiled libraries due to
compiler-technical reasons). So what if I need to "include someone else's
code in my program"? (The biggest issue with that for me would be the
usage license of the library, but that's completely tangential to the
subject.)
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Warp wrote:
> > Let's take a better example: Every time I want to use std::vector,
> > I have to #include <vector> in the source file where I want to do so.
> > Is there any advantage to this?
> For C++ and templates, yes. Altho (and I know you'll go apeshit over this
> comment) C# manages not to need the source code for generics like that.
It's not so much a question of making it work as much as a question of
optimization.
For example, if you create your own class or struct which has a few
member variables, and then you instantiate a vector of that type, it will
be quite space-optimal: Every element in the vector will only consume as
much memory as the size of the object. There is no ancillary data needed.
Of course the second efficiency advantage is that the compiler will be
able to inline code and to perform type-specific optimizations (for example,
sorting a vector of ints will be very efficient because the compiler will
be able to inline the element comparisons directly into the sorting routine
as a machine code register comparison opcode).
This still doesn't make it technically impossible to compile templates
into precompiled libraries. In fact, the current C++ standard defines such
a possibility (the so-called "export templates"). The only major problem
with export templates is that it's technically extremely difficult and
laborious to implement in compilers, which is why there's only one major
C++ compiler that supports it (and it's because of this that, faced with
the harsh realities of the marketplace, the standardization committee is
going to drop the feature from the next standard).
The problem is that templates need to be instantiated in the context
where they are used. Or in the case of export templates, the context needs
to be "brought" where the export template is being instantiated. This is
an extremely complicated thing to do.
For example, you could have this in one source file:
//--------------------------------------------------------
namespace
{
// 'Point' is a type local to this compilation unit
struct Point { int x, y; }
std::vector<Point> points;
}
//--------------------------------------------------------
And then you could have this in another source file:
//--------------------------------------------------------
namespace
{
// 'Point' is a type local to this compilation unit
struct Point { double x, y; }
std::vector<Point> points;
}
//--------------------------------------------------------
With regular templates this isn't any problem at all, and it's trivial
for compilers to handle. With export templates the problem is enormously
harder. (Basically, the 'vector' template class, if it was an export
template, would be instantiated at the linking stage in its own compilation
unit, with its own context, but it needs to also know the context in which
it was used, as above. The compiler needs to somehow carry all the context
information to the template instantiation process at the linking stage.)
And as far as I understand, the above example is just one of the *minor*
complexities in this whole thing.
On the other hand, it's not technically impossible, and it has been done,
so in principle it would be possible to have precompiled template libraries.
(They would only be slightly less efficient because functions which are not
implemented in the header file would not be inlined. OTOH this isn't different
from regular functions.)
As far as I understand "generics" do not handle things "inline" and
"by value", but instead simply handle references, and basically the only
thing they do is that they allow you to skip doing explicit upcasting.
Generics do not allow things like template metaprogramming, template
specialization, and such. (Well, this at least with Java generics. I have
no idea about C#. Also, at least in Java, you can't handle primitive types
with generics.)
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |