POV-Ray : Newsgroups : povray.off-topic : Teach yourself C++ in 21 days Server Time
29 Jul 2024 18:19:41 EDT (-0400)
  Teach yourself C++ in 21 days (Message 109 to 118 of 168)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Francois Labreque
Subject: Re: Teach yourself C++ in 21 strange malfunctions
Date: 20 Apr 2012 10:36:54
Message: <4f917486@news.povray.org>

>>>> in any case, even humble C can do that, provided a Makefile is ready.
>>>> heck, Makefiles are language-agnostic even...
>>>
>>> Makefiles only work on Unix. :-P But hey, you can write a simple script
>>> to build your project under Windows.
>>
>> WAT?
>
> To tell you the truth, I don't even /like/ Make all that much. (I think
> it's the tab characters. Or the slightly clunky way it deals with
> targets that aren't files.) I only really use it for building C, because
> it's either that or work out how to invoke the compiler manually...
>
> But as I say, a tiny amount of shell scripting will automate most tasks,
> without the need for Make.
>

If you like reinventing the wheel... ;)

>>> The /real/ problem, of course, is that you have to open a command
>>> window, CD to the right folder, and type in "make program1" or whatever.
>>> This takes significantly longer than pressing F7 (or whatever).
>>
>> Which you only have to do once... After that you only need to hit
>> ALT-TAB and the up arrow.
>
> That works great - /until/ your command history has more than one
> command in it. E.g., if you use the same window to run the compiler, run
> the main program, and control your SCM. Then you end up jabbing up-arrow
> endlessly, or executing the wrong command, or both. Very annoying.
>

You know you can open more than one command promt.

> (I wonder why nobody has yet thought of making an editor where you can
> add buttons to the toolbar and kind arbitrary commands to them? You
> could even give them keyboard shortcuts...)
>

Dare I say it?  Oh... sure... why not...

Emacs does it.  ;)

Notepad++ too.

>> Starting notepad++ and a command prompt take significantly less time
>> than starting any IDE.
>
> Depends on the IDE. Some are slower than others. I do take your point
> though - some of them do take an absurd amount of time to start. Then
> again, "you only do that once". :-P
>
>>> Sure, once you take your hands off the keyboard and onto the mouse to
>>> switch from the text editor window to the command prompt window. :-P
>>>
>>
>> As mentioned previously, ALT-TAB. Much faster.
>
> And if in the middle of your coding session, you quickly switch to your
> email client to check something, next time you try to use Alt+Tab, it
> takes you to the wrong window.
>

Keep you thumb on ALT, and hit TAB repeatedly until you get to the right 
application.

> It sounds trivial, but it's really very, very annoying.
>
> (It becomes even more fun when what you're working on involves more
> windows. E.g., right now I'm writing some TeX, so I have my text editor
> open, my command window open, and my DVI window open. You can 100%
> guarantee that almost every time I change window I change to the wrong
> one...)

I usually have my e-mail client, corporate instant messenger app ( 
usually with a few chat windows opened), 3 or four browser windows, a 
couple Excel sheets, two VPN apps (don't ask!) and a couple other 
network monitoring apps loaded at any one time.  Mastering the ALT-TAB 
combo is much, much, much, faster than using the mouse to switch apps 
from the task bar.  Not to mention a lot cheaper than a dozen 
occupational therapy sessions due to tendinitis or carpal tunnel syndrome.

-- 
/*Francois Labreque*/#local a=x+y;#local b=x+a;#local c=a+b;#macro P(F//
/*    flabreque    */L)polygon{5,F,F+z,L+z,L,F pigment{rgb 9}}#end union
/*        @        */{P(0,a)P(a,b)P(b,c)P(2*a,2*b)P(2*b,b+c)P(b+c,<2,3>)
/*   gmail.com     */}camera{orthographic location<6,1.25,-6>look_at a }


Post a reply to this message

From: Invisible
Subject: Re: Days 1-5
Date: 20 Apr 2012 10:41:47
Message: <4f9175ab$1@news.povray.org>
On 20/04/2012 03:29 PM, Warp wrote:
> Invisible<voi### [at] devnull>  wrote:
>>> class X; // declaration of X
>
>> Ah, I see. This is the fact I was looking for. :-)
>
>> So this does... what? Tells the compiler "hey, this type exists, but I'm
>> not going to tell you anything about it"?
>
>    It tells that there's a class named X.
>
>    From that point forward you can do anything with that type that does not
> require calling its member functions or accessing its contents. (In other
> words, you can handle pointers and references of that type.) You can also
> make further declarations using it (such as declaring it as the return
> type of a function).
>
>    Doing anything else with an object of that type requires a full class
> definition, but that can be done later in the code.
>
>    This allows inter-dependency between classes.

Right. So I can declare functions that take it or return it, and I can 
declare (but not define) variables of that type. And then I can #include 
the full description before I try implementing anything that actually 
needs to touch it "for real". (?)

>    What I mean is that you can't do this:
>
> class A { B b; };
> class B { A a; };
>
>    That would be a pair of infinitely large classes.

Yes, clearly that can't work.


Post a reply to this message

From: Invisible
Subject: Re: Teach yourself C++ in 21 strange malfunctions
Date: 20 Apr 2012 10:47:30
Message: <4f917702$1@news.povray.org>
>> To tell you the truth, I don't even /like/ Make all that much. (I think
>> it's the tab characters. Or the slightly clunky way it deals with
>> targets that aren't files.) I only really use it for building C, because
>> it's either that or work out how to invoke the compiler manually...
>>
>> But as I say, a tiny amount of shell scripting will automate most tasks,
>> without the need for Make.
>
> If you like reinventing the wheel... ;)

Not so much "reinventing the wheel". More like "I don't actually need 
the full power of Make".

>> That works great - /until/ your command history has more than one
>> command in it. E.g., if you use the same window to run the compiler, run
>> the main program, and control your SCM. Then you end up jabbing up-arrow
>> endlessly, or executing the wrong command, or both. Very annoying.
>
> You know you can open more than one command promt.

...which just changes the problem from "hitting the up arrow the right 
number of times" to "hitting Alt+Tab the right number of times".

>> (I wonder why nobody has yet thought of making an editor where you can
>> add buttons to the toolbar and kind arbitrary commands to them? You
>> could even give them keyboard shortcuts...)
>
> Dare I say it? Oh... sure... why not...
>
> Emacs does it. ;)

Yeah, but... WHY WOULD YOU DO THAT? >_<

>>> As mentioned previously, ALT-TAB. Much faster.
>>
>> And if in the middle of your coding session, you quickly switch to your
>> email client to check something, next time you try to use Alt+Tab, it
>> takes you to the wrong window.
>
> Keep you thumb on ALT, and hit TAB repeatedly until you get to the right
> application.

I know that. It's still more fiddly and error-prone than just jabbing a 
button that always does the same thing, regardless of which application 
window you used most recently.

>> (It becomes even more fun when what you're working on involves more
>> windows.
>
> Mastering the ALT-TAB
> combo is much, much, much, faster than using the mouse to switch apps
> from the task bar.

It depends how far back in the stack you need to cycle. At some point, 
the mouse becomes faster.

> Not to mention a lot cheaper than a dozen
> occupational therapy sessions due to tendinitis or carpal tunnel syndrome.

Nobody gets tendinitis just from using a mouse.

You /might/ get tendinitis from working on a production line, executing 
the exact same pick up, solder, put down movements eight times per 
minute for hours on end without stopping for so much as twenty seconds 
for a break. (Yes, I've tried it.) You don't get it just from operating 
a computer normally. Not if you have sane desk height, etc.


Post a reply to this message

From: Warp
Subject: Re: Days 1-5
Date: 20 Apr 2012 11:16:53
Message: <4f917de4@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> Right. So I can declare functions that take it or return it, and I can 
> declare (but not define) variables of that type.

  Btw, a class that has only been declared but not defined (in other words,
you have only said "class X;") is called an "incomplete type" in C++
parlance.

  You can have pointers and references to an incomplete type, and you can
use it wherever a type is required (without any actual object), such as in
function declarations. In other words, you can do eg. like this:

//--------------------------------------------------------------------
class MyClass;

// Function that takes an object of type MyClass as parameter and
// returns another object of that type:
MyClass aFunction(MyClass object);
//--------------------------------------------------------------------

  (Of course if you try to *call* that function without a full class
definition, you'll get a compiler error.)

  You could also declare an extern variable of that type (although that's
a quite rare circumstance, but it's still possible). In other words:

//--------------------------------------------------------------------
class MyClass;

extern MyClass aGlobalObject;
//--------------------------------------------------------------------

  One situation where you ought to not be able to do it, but you can, due
to a quirk in the language, is deleting an object using an incomplete
type. In other words, this will compile, albeit usually with a warning:

//--------------------------------------------------------------------
class MyClass;

void foo(MyClass* objPtr)
{
    delete objPtr; // Never do this!
}
//--------------------------------------------------------------------

  The major, major problem with that is that, while the memory taken by
that object will be freed, the destructor of the object will *not* be
called. Bad things will happen. (There was some reasoning why it's
nevertheless allowed by the standard, but I don't remember now what it
was.)

  This, however, will work ok:

//--------------------------------------------------------------------
class MyClass

// An extern function that allocates an object of type MyClass and
// returns it:
std::shared_ptr<MyClass> gimmeAnObjectOfTypeMyClass();

void foo()
{
    std::shared_ptr<MyClass> ptr = gimmeAnObjectOfTypeMyClass();

    // When foo() is exited, the allocated object will be destroyed
    // properly. In other words, its destructor will be called ok.
}
//--------------------------------------------------------------------

  The implementation of gimmeAnObjectOfTypeMyClass() (in a completely
different source file) can simply be:

//--------------------------------------------------------------------
#include "FullDefinitionOfMyClass.hh"

std::shared_ptr<MyClass> gimmeAnObjectOfTypeMyClass()
{
    return new MyClass(); // Constructs and returns an object of MyClass
}
//--------------------------------------------------------------------

  In the code above where the returned object is destroyed, at no point do we
have a full definition of 'MyClass'. Nevertheless, when the std::shared_ptr
that's managing it goes out of scope, it will delete it and its destructor
will be called. It achieves this through template magic.

  (Nevertheless, you seldom need to resort to this kind of trickery in
practical code. At least not this explicitly. Don't take this as an
example of what kind of code people usually write in C++.)

-- 
                                                          - Warp


Post a reply to this message

From: Invisible
Subject: Re: Days 1-5
Date: 20 Apr 2012 11:25:44
Message: <4f917ff8$1@news.povray.org>
On 20/04/2012 04:16 PM, Warp wrote:

>    Btw, a class that has only been declared but not defined (in other words,
> you have only said "class X;") is called an "incomplete type" in C++
> parlance.

Right.

>    You can have pointers and references to an incomplete type, and you can
> use it wherever a type is required (without any actual object), such as in
> function declarations. In other words, you can do eg. like this:
>
> //--------------------------------------------------------------------
> class MyClass;
>
> // Function that takes an object of type MyClass as parameter and
> // returns another object of that type:
> MyClass aFunction(MyClass object);
> //--------------------------------------------------------------------
>
>    (Of course if you try to *call* that function without a full class
> definition, you'll get a compiler error.)

How about if you try to write the function body without the full class? 
I'm presuming that will fail too, since the compiler needs to know how 
much space to allocate...

>    You could also declare an extern variable of that type (although that's
> a quite rare circumstance, but it's still possible).

Right. But presumably you can't actually /create/ the variable, because 
you don't know it's size. (?)

>    One situation where you ought to not be able to do it, but you can, due
> to a quirk in the language, is deleting an object using an incomplete
> type. In other words, this will compile, albeit usually with a warning:
>
> //--------------------------------------------------------------------
> class MyClass;
>
> void foo(MyClass* objPtr)
> {
>      delete objPtr; // Never do this!
> }
> //--------------------------------------------------------------------
>
>    The major, major problem with that is that, while the memory taken by
> that object will be freed, the destructor of the object will *not* be
> called. Bad things will happen. (There was some reasoning why it's
> nevertheless allowed by the standard, but I don't remember now what it
> was.)

Oooohhhhh that's evil.

>    In the code above where the returned object is destroyed, at no point do we
> have a full definition of 'MyClass'. Nevertheless, when the std::shared_ptr
> that's managing it goes out of scope, it will delete it and its destructor
> will be called. It achieves this through template magic.

Sure. When the template expands, we /do/ have the full class spec, so it 
works. (At least, I'm presuming that's what happens.)

>    (Nevertheless, you seldom need to resort to this kind of trickery in
> practical code. At least not this explicitly. Don't take this as an
> example of what kind of code people usually write in C++.)

Oh hell yes - I don't intend on trying this... ever, actually.


Post a reply to this message

From: Warp
Subject: Re: Days 1-5
Date: 20 Apr 2012 12:06:00
Message: <4f918968@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> >    In the code above where the returned object is destroyed, at no point do we
> > have a full definition of 'MyClass'. Nevertheless, when the std::shared_ptr
> > that's managing it goes out of scope, it will delete it and its destructor
> > will be called. It achieves this through template magic.

> Sure. When the template expands, we /do/ have the full class spec, so it 
> works. (At least, I'm presuming that's what happens.)

  The std::shared_ptr object in that example doesn't see the complete
definition of the class at any moment, because it hasn't been defined.
It gets initialized with another instance of std::shared_ptr (which was
created in that function somewhere else), but it itself doesn't see the
full definition of the class it's managing.

  To recapitulate:

//---------------------------------------------------------------------
class MyClass; // incomplete type

// A function somewhere else that returns a std::shared_ptr object:
std::shared_ptr<MyClass> foo();

void bar()
{
    std::shared_ptr<MyClass> ptr;
    // *this* shared_ptr object does not see a MyClass definition
    // at any point

    ptr = foo();
    // The shared_ptr returned by foo() is assigned to it.

    // Now when bar() ends, 'ptr' will destroy the object.
    // And properly at that. The destructor will be called ok.
    // Yet 'ptr' never sees the full definition of 'MyClass'.
}
//---------------------------------------------------------------------

  Even though 'ptr' above at no point sees the full definition of
'MyClass', it just works. It does so by employing template magic.

-- 
                                                          - Warp


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Teach yourself C++ in 21 strange malfunctions
Date: 20 Apr 2012 13:02:44
Message: <4f9196b4$1@news.povray.org>
On 20/04/2012 02:41 AM, Darren New wrote:
> Plus, the IDE for Smalltalk doesn't really deal too much with the fact
> that it's OO. It didn't do any of the sorts of completion you're talking
> about.

Well, to be fair, since Smalltalk isn't statically typed, you'd be 
hard-pressed to figure out what messages are applicable to a given 
variable. ;-)


Post a reply to this message

From: Darren New
Subject: Re: Days 1-5
Date: 20 Apr 2012 23:39:43
Message: <4f922bff$1@news.povray.org>
On 4/20/2012 1:28, Invisible wrote:
> So what /was/ the Motorola 68000 designed to be programmed in then?

I would guess C or Algol or some such. There's a separation between address 
and data registers, there's a stack pointer, there are various addressing 
modes that (IIRC) include auto-increment, etc.

The 8086 was designed to be efficient for Pascal, for example. But not too 
efficient, given that it doesn't have proper frame pointers.

>>> I dislike code that's so littered with comments that you can't see the
>>> code
>>
>> Except in assembler.
>
> ?

At least on machines designed to be programmed in assembler, one can 
generally put a useful and informative comment on pretty much every line.

> It worries me that we're still using a language who's fundamental design
> decisions are based on hardware first produced in the 1970s.

Yep.

>>> So much for C and C++ being for system-level programming. :-P
>>
>> It was never very *good* for it. It was just better than its competitors
>> of the time.
>
> Jesus, did it even *have* any competitors?!

Assembly. ;-)  Probably LISP.  COBOL to a large extent.

>> No, of course not. C doesn't provide any way to ask for a type based on
>> what you need. You can only ask for types based on what the CPU
>> provides
>
> OK, well IA-32 provides 80-bit floats. So... is there a standard way to get
> them?

AFAIK, you have float and double. Maybe there's now a long double, but I 
don't recall.

> You'd expect part of the language's basic syntax to be, you know... part of
> the language's basic syntax. But it isn't. It's just a regular operator,
> which means you can use it in places where you shouldn't be putting random
> commas, and that makes it do strange stuff. (And, being C, this isn't
> checked in any way.)

Why would you put randomg *anything* in? This isn't a sonnet. It's computer 
code.  Why would you put random commas in any more than you put random quote 
marks in?

> The /logical/ thing is for a function that doesn't mention a return type to
> default to returning nothing. And yet, it doesn't. It arbitrarily defaults
> to int. Not bool, not void*, not w_char, but int. No reason, it just does.

Remember the compilation model.  Plus, "void" is a relatively recent 
development.

> I forget who said it: comprehension = 2 ^ -precision.

You just have to think mathely.


-- 
Darren New, San Diego CA, USA (PST)
   "Oh no! We're out of code juice!"
   "Don't panic. There's beans and filters
    in the cabinet."


Post a reply to this message

From: Darren New
Subject: Re: Days 5-
Date: 20 Apr 2012 23:43:18
Message: <4f922cd6$1@news.povray.org>
On 4/20/2012 0:15, Le_Forgeron wrote:
> Linker will not remove either. (because it has no way to know if the one
> in unit A is identical to the one in unit B: naming is no use, you might
> have compiled unit A with the version of Monday, and unit B with the
> version of Saturday.

I don't think mis-matched declarations were ever something that C worried 
about. Does C++ actually check that sort of thing now?

I know that with Ada, you can't link incompatible object code, in the sense 
that if you have (the equivalent of) A.h and A.c and B.c, and B.c uses A.h, 
then both A.c and B.c have to get compiled after A.h gets compiled. If you 
go change A.h after you've already compiled A.c, you can no longer link 
against the old binary. The compiler winds up doing stuff like putting the 
hashes of every header file (equivalent) into each object code generated, 
and then checking they all match up at link time.

-- 
Darren New, San Diego CA, USA (PST)
   "Oh no! We're out of code juice!"
   "Don't panic. There's beans and filters
    in the cabinet."


Post a reply to this message

From: Darren New
Subject: Re: Days 5-
Date: 20 Apr 2012 23:45:55
Message: <4f922d73$1@news.povray.org>
On 4/20/2012 5:11, Warp wrote:
> Darren New<dne### [at] sanrrcom>  wrote:
>>> The book claims that if you write a function body inside a class definition,
>>> that makes the method inline. Is this true? I thought there was no
>>> difference either way...
>
>> It *has* to be.
>
>    It doesn't *have* to be (any more than any other function defined in a
> header file, or anywhere else), but the standard says it is, and so it is.

I meant, it *has* to be or it will link but won't compile, because you wind 
up compiling a version of the header file in each .c file it's included in.

Sure, it doesn't *have* to be implicitly inline, but since every function in 
a header file is either inline, or shouldn't be in the header file in the 
first place, or fails to link, it made sense to make the default "yes, 
please work."

-- 
Darren New, San Diego CA, USA (PST)
   "Oh no! We're out of code juice!"
   "Don't panic. There's beans and filters
    in the cabinet."


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.