POV-Ray : Newsgroups : povray.off-topic : Adventures with C++ Server Time
12 Oct 2026 02:46:15 EDT (-0400)
  Adventures with C++ (Message 1 to 50 of 65)  
Goto Latest 50 Messages Next 15 Messages >>>
From: Orchid Win7 v1
Subject: Adventures with C++
Date: 13 May 2013 14:09:29
Message: <51912c59$1@news.povray.org>
Today, I wrote a parser in C++.

The slightly alarming thing is that it almost works correctly too. (It's 
not quite finished yet.)

And no segfaults! It turns out that if you throw enough STL containers 
at the problem, you can make it work without any manual pointer 
manipulation. (I shudder to think what the performance is like... 
Fortunately the input to the parser will always be small.)

It took 4 employees approximately 4 hours to get VisualStudio to 
successfully compile and link the code. (There are external 
dependencies, and the program is split into two projects which have to 
cross-reference each other correctly, and so on.) VS is really very 
clunky with C++ code.

It then took me about half an hour to write the parser test cases, and 
the rest of today to write the actual parser. Nested subexpression 
parsing still isn't working quiet right yet, so I need to go take a look 
at that.

I must say, when I signed up for a job as a C# programmer, I didn't 
think I'd spend 3 months writing Bash scripts, two weeks writing 
VBScript and then a day writing C++ code... :-P


Post a reply to this message

From: Nekar Xenos
Subject: Re: Adventures with C++
Date: 13 May 2013 14:12:36
Message: <op.ww1bi91yufxv4h@xena>
On Mon, 13 May 2013 20:09:39 +0200, Orchid Win7 v1 <voi### [at] devnull> wrote:

> Today, I wrote a parser in C++.
>

> I must say, when I signed up for a job as a C# programmer, I didn't  
> think I'd spend 3 months writing Bash scripts, two weeks writing  
> VBScript and then a day writing C++ code... :-P

Sounds exciting ;)

-- 
-Nekar Xenos-


Post a reply to this message

From: Kenneth
Subject: Re: Adventures with C++
Date: 14 May 2013 08:55:01
Message: <web.5192330f676156f1c2d977c20@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:

>
> I must say, when I signed up for a job as a C# programmer, I didn't
> think I'd spend 3 months writing Bash scripts, two weeks writing
> VBScript and then a day writing C++ code... :-P

It's the overly-detailed, over-inflated job 'qualifications' requirements :-P

To be a brick-layer these days, the qualifications probably read: "Must be
familiar with silicon/water chemistry on the atomic level, plus five years of
academic training in geometry. Phd in architectural design a plus."


Post a reply to this message

From: scott
Subject: Re: Adventures with C++
Date: 14 May 2013 08:59:56
Message: <5192354c@news.povray.org>
> It took 4 employees approximately 4 hours to get VisualStudio to
> successfully compile and link the code. (There are external
> dependencies, and the program is split into two projects which have to
> cross-reference each other correctly, and so on.) VS is really very
> clunky with C++ code.

After having spent a few years with VS and C#, a few months ago I tried 
again VS for C++ and agree it's still very clunky in comparison. Not 
sure if that's more a limitation of C++ compared to C#, but it's 
certainly not as user friendly.

> I must say, when I signed up for a job as a C# programmer, I didn't
> think I'd spend 3 months writing Bash scripts, two weeks writing
> VBScript and then a day writing C++ code... :-P

You mean you haven't found an excuse to use POV yet!?! (and then 
obviously the newsgroups as well...)


Post a reply to this message

From: Warp
Subject: Re: Adventures with C++
Date: 14 May 2013 13:04:45
Message: <51926ead@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
> And no segfaults! It turns out that if you throw enough STL containers 
> at the problem, you can make it work without any manual pointer 
> manipulation.

When using the standard containers, one should know how they work and
what they are doing, in terms of efficiency. For example, passing them
by value eg. as function parameters is inefficient, and that should always
be done by reference, if possible.

And also, of course, use the right tool for the job. It makes no sense
to use, for example, std::list for something that std::vector will do.
And if your array is of static size, use std::array instead of std::vector
(especially if it's eg. a smallish array that's a member variable of a
class that gets instantiated a lot.)

You can still index those out-of-bounds, but many compilers, eg. Visual
Studio, will add boundary checks when compiling in debug mode. (The
boundary checks are not used in release mode for efficiency.)

-- 
                                                          - Warp


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Adventures with C++
Date: 14 May 2013 13:18:29
Message: <519271e5$1@news.povray.org>
> You mean you haven't found an excuse to use POV yet!?! (and then
> obviously the newsgroups as well...)

Well, I did use my IRTC entry for some of our test data...


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Adventures with C++
Date: 14 May 2013 13:21:51
Message: <519272af$1@news.povray.org>
On 14/05/2013 06:04 PM, Warp wrote:
> When using the standard containers, one should know how they work and
> what they are doing, in terms of efficiency. For example, passing them
> by value eg. as function parameters is inefficient, and that should always
> be done by reference, if possible.

How about std::string? Presumably it's a bad idea to pass that by value 
either...

> And also, of course, use the right tool for the job. It makes no sense
> to use, for example, std::list for something that std::vector will do.
> And if your array is of static size, use std::array instead of std::vector

All this stuff is pretty dynamic. I have no idea how big the expression 
I'm parsing will be until after I finish parsing it.

I'm sure if you could see my code, you'd probably have a heart attack 
over all the highly inefficient stuff it's doing. Then again, it gets 
run once at application start-up, parsing a few dozen strings that are 
mostly a dozen characters long each, so...

(Perhaps the biggest inefficiency is having a lot of zero-element 
vectors laying around. I have no idea what the space overhead for that 
is. But I also have no idea how to avoid it.)


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Adventures with C++
Date: 14 May 2013 13:24:06
Message: <51927336$1@news.povray.org>
On 13/05/2013 07:09 PM, Orchid Win7 v1 wrote:
> The slightly alarming thing is that it almost works correctly too. (It's
> not quite finished yet.)

At about 2AM, I rolled over in bed and realised why this is broken.

   std::vector<Stuff> current = stack.back();
   current.push_back(more_stuff);

Uh, yes... that doesn't do what I meant AT ALL! >_<

Still, I'm impressed I managed to figure out the bug when I don't even 
have access to the code...


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Adventures with C++
Date: 14 May 2013 13:29:54
Message: <51927492$1@news.povray.org>
On 13/05/2013 07:09 PM, Orchid Win7 v1 wrote:
> It took 4 employees approximately 4 hours to get VisualStudio to
> successfully compile and link the code.

But that's nothing compared to how long it took to get VS to produce a 
DLL, and then get C# to successfully call this DLL without access 
violations... >_<


Post a reply to this message

From: Warp
Subject: Re: Adventures with C++
Date: 14 May 2013 15:46:09
Message: <51929480@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
> On 14/05/2013 06:04 PM, Warp wrote:
> > When using the standard containers, one should know how they work and
> > what they are doing, in terms of efficiency. For example, passing them
> > by value eg. as function parameters is inefficient, and that should always
> > be done by reference, if possible.

> How about std::string? Presumably it's a bad idea to pass that by value 
> either...

It depends on the implementation.

Since std::string is so ubiquitous, many standard library implementations
have optimizations that make copying them fast (some use short string
optimization, some use lazy copying...), but that's in no way a guarantee.

There's usually no reason to not to use a std::string reference if it
suffices. Only copy when you have to.

-- 
                                                          - Warp


Post a reply to this message

From: nemesis
Subject: Re: Adventures with C++
Date: 14 May 2013 19:35:01
Message: <web.5192ca03676156f1ebb90cbd0@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
> spend 3 months writing Bash scripts, two weeks writing
> VBScript and then a day writing C++ code... :-P

you truly suck at bash ;)


Post a reply to this message

From: Orchid Win7 v1
Subject: An actual C++ question
Date: 15 May 2013 15:58:52
Message: <5193e8fc$1@news.povray.org>
OK, so I have a class that looks like this:

   class Foobar
   {
     private:
       Secrets secrets;
     public:
       int Foo1();
       int Foo2();
       int Foo3();
   };

Now I want to put that in a header file. What I *actually* want to write is

   class Foobar
   {
     public:
       int Foo1();
       int Foo2();
       int Foo3();
   };

However, this doesn't work at all, because now the "real" Foobar class 
is a different size to what all the clients of Foobar are expecting. 
General mayhem ensues.

So I have to put the entire class definition into the header file. But 
that means I have to put Secrets into the header file too - a data 
structure that clients have absolutely no reason to know anything about. 
(And I have to include everything that Secrets mentions, and everything 
that those things mention, and...)

I thought perhaps I could just write an empty forward declaration, but 
unsurprisingly that doesn't work; the compiler needs size information.

After Googling it, the only solution I could find was to make the 
private field a *pointer* to the secret data. Now I can put a dummy 
forward declaration in the header file, and define the real data 
structure in the implementation, where it belongs.

And now I'm doing manual memory management. >_<

The example I got from Google shows a class with a constructor and a 
destructor - so, following Warp's teachings, my immediate reaction is 
"what the hell happens if somebody copies the object?" I fear the 
secrets will be double-freed at some point.

My question is... Is there some simple change I might make to the code 
to avoid all the gotchas of manual memory management?

I mean, there will only ever be one object, created in one place, so it 
"should" be fine... but it still makes me nervous. If some day somebody 
tries to use the code in a new way, I don't want it to suddenly fail in 
a spectacular way so some poor sod has to spend 3 weeks trying to figure 
out why...


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Adventures with C++
Date: 15 May 2013 15:59:55
Message: <5193e93b@news.povray.org>
On 15/05/2013 12:34 AM, nemesis wrote:
> Orchid Win7 v1<voi### [at] devnull>  wrote:
>> spend 3 months writing Bash scripts, two weeks writing
>> VBScript and then a day writing C++ code... :-P
>
> you truly suck at bash ;)

Oh, and I suppose *you* know exactly how to parse the output of sfdisk 
to generate a valid mtab entry? :-P


Post a reply to this message

From: nemesis
Subject: Re: Adventures with C++
Date: 15 May 2013 17:25:00
Message: <web.5193fcc1676156f1ebb90cbd0@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
> On 15/05/2013 12:34 AM, nemesis wrote:
> > Orchid Win7 v1<voi### [at] devnull>  wrote:
> >> spend 3 months writing Bash scripts, two weeks writing
> >> VBScript and then a day writing C++ code... :-P
> >
> > you truly suck at bash ;)
>
> Oh, and I suppose *you* know exactly how to parse the output of sfdisk
> to generate a valid mtab entry? :-P

just a joke about the duration of your bash programming versus C++ :)


Post a reply to this message

From: Warp
Subject: Re: An actual C++ question
Date: 15 May 2013 17:44:06
Message: <519401a6@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
> So I have to put the entire class definition into the header file. But 
> that means I have to put Secrets into the header file too - a data 
> structure that clients have absolutely no reason to know anything about. 

If having the internal-implementation-detail as a member variable of
the class is something you just must avoid, and especially if this is
a class that doesn't get instantiated a lot, then the solution is to
use the Pimpl idiom, which regardless of the funny name, is exactly what
you described. In other words, make a forward declaration of that private
class and just have a pointer to it as member.

> My question is... Is there some simple change I might make to the code 
> to avoid all the gotchas of manual memory management?

Yes: Use std::shared_ptr instead of a raw pointer. In other words, you do
it like this:

    class PrivateClass;

    class MyClass
    {
        std::shared_ptr<PrivateClass> privateObject;
    };

Then in the implementation of MyClass just do a:

    privateObject = new PrivateClass;

and then you can forget about managing it yourself.

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: An actual C++ question
Date: 15 May 2013 17:53:17
Message: <519403cd@news.povray.org>
Warp <war### [at] tagpovrayorg> wrote:
>     class PrivateClass;

>     class MyClass
>     {
>         std::shared_ptr<PrivateClass> privateObject;
>     };

Oh, and take into account that if instances of MyClass are copied around,
the copies will share the one and same PrivateClass object. That will not
get deep-copied. (That's what the "shared ptr" means, actually.)

If you want to avoid MyClass being copied around, that can be disabled.
(Of course this restricts the ways in which the class can be used, so
it's always a compromise.)

Another possibility is to write a copy constructor and a copy assignment
operator that deep-copies the private object... It all depends on how
exactly you need MyClass to behave.

-- 
                                                          - Warp


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: An actual C++ question
Date: 16 May 2013 03:39:25
Message: <51948d2d$1@news.povray.org>
>>      class PrivateClass;
>
>>      class MyClass
>>      {
>>          std::shared_ptr<PrivateClass>  privateObject;
>>      };

OK. That seems easy enough.

> Oh, and take into account that if instances of MyClass are copied around,
> the copies will share the one and same PrivateClass object. That will not
> get deep-copied. (That's what the "shared ptr" means, actually.)

There "should" only ever be one instance of this class; I'd just like to 
avoid the program exploding if somebody *does* copy that instance for 
some reason. A shallow copy is acceptable.


Post a reply to this message

From: scott
Subject: Re: An actual C++ question
Date: 16 May 2013 10:55:52
Message: <5194f378$1@news.povray.org>
> There "should" only ever be one instance of this class; I'd just like to
> avoid the program exploding if somebody *does* copy that instance for
> some reason. A shallow copy is acceptable.

Is there a C++ equivalent to the C# static class? That would ensure at 
compile-time that nobody tried to create an(other) instance.


Post a reply to this message

From: Warp
Subject: Re: An actual C++ question
Date: 16 May 2013 11:27:04
Message: <5194fac8@news.povray.org>
scott <sco### [at] scottcom> wrote:
> > There "should" only ever be one instance of this class; I'd just like to
> > avoid the program exploding if somebody *does* copy that instance for
> > some reason. A shallow copy is acceptable.

> Is there a C++ equivalent to the C# static class? That would ensure at 
> compile-time that nobody tried to create an(other) instance.

You could use a namespace instead of a class. Private implementation can
then all go to the source file, away from the header file.

On the other hand, this limits where you can use this "pseudoclass" and
it could be difficult to maintain backwards compatibility if you ever
wanted to change it so that more than one instance could be created.

Of course you could have a class that only has static member functions...

-- 
                                                          - Warp


Post a reply to this message

From: Le Forgeron
Subject: Re: An actual C++ question
Date: 16 May 2013 13:19:26
Message: <5195151e$1@news.povray.org>
Le 16/05/2013 17:27, Warp nous fit lire :
> scott <sco### [at] scottcom> wrote:

>> Is there a C++ equivalent to the C# static class? That would ensure at 
>> compile-time that nobody tried to create an(other) instance.
> 

You can either have all methods of a class static, or use a singleton
pattern.

> You could use a namespace instead of a class. Private implementation can
> then all go to the source file, away from the header file.
> 
> On the other hand, this limits where you can use this "pseudoclass" and
> it could be difficult to maintain backwards compatibility if you ever
> wanted to change it so that more than one instance could be created.
> 
> Of course you could have a class that only has static member functions...
>


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Adventures with C++
Date: 16 May 2013 13:46:20
Message: <51951b6c@news.povray.org>
On 14/05/2013 06:29 PM, Orchid Win7 v1 wrote:
> But that's nothing compared to how long it took to get VS to produce a
> DLL, and then get C# to successfully call this DLL without access
> violations... >_<

But THAT is nothing compared to the trouble we had trying to build a 
Linux "shared object" and getting Mono to load that...

I can still hardly believe that this whole improbable contraption 
actually ended up WORKING in the end! o_O


Post a reply to this message

From: Warp
Subject: Re: An actual C++ question
Date: 16 May 2013 14:57:33
Message: <51952c1d@news.povray.org>
Le_Forgeron <jgr### [at] freefr> wrote:
> You can either have all methods of a class static, or use a singleton
> pattern.

If you are using an enforced singleton, and you don't want to expose
*any* implementation detail to the outside, one possibility would be
to do this:

//------------------------------------------------------------
// In the header file:
// ------------------

class TheClass
{
 public:
    virtual void someFunction() = 0;
    virtual int anotherFunction(int parameter) = 0;
    virtual void aThirdFunction(double, double) = 0;
};

TheClass& theClassInstance();
//------------------------------------------------------------

//------------------------------------------------------------
// In the implementation file:
// --------------------------

#include "TheClass.hh"

namespace
{
    class TheActualClass: public TheClass
    {
        struct InnerType { int a, b; }

        int privateMember;
        double anotherPrivateMember;
        InnerType aThirdPrivateMember;

        void privateFunction();

     public:
        TheActualClass() { /* constructor */ }

        virtual void someFunction()
        {
            // implement it here
        }

        virtual int anotherFunction(int parameter)
        {
            // implement it here
        }

        virtual void aThirdFunction(double, double)
        {
            // implement it here
        }
    };
}

TheClass& theClassInstance()
{
    static TheActualClass actualClassInstance;
    return actualClassInstance;
}
//------------------------------------------------------------

-- 
                                                          - Warp


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: An actual C++ question
Date: 17 May 2013 13:20:28
Message: <519666dc$1@news.povray.org>
On 16/05/2013 08:39 AM, Orchid Win7 v1 wrote:
>>> class PrivateClass;
>>
>>> class MyClass
>>> {
>>> std::shared_ptr<PrivateClass> privateObject;
>>> };
>
> OK. That seems easy enough.

I entered this into VisualStudio, and it worked great.

However, when I tried to compile it under Linux, GCC refused to accept it.

First, VS seems to somehow allow you to compile things even without 
actually importing the necessary include files. (E.g., it will happily 
accept std::shared_ptr even though I didn't #include <memory>.) GCC 
demands that you actually specify the include files [like you'd expect]. 
Weird, but true.

Second, it seems this "feature" only exists in C++11. I don't know what 
GCC is defaulting to, but apparently you have to add a switch to tell it 
to accept C++11. And when I do that, my code compiles perfectly, but the 
rest of the codebase breaks spectacularly.

So, in summary, I had to revert everything back to how it was. *sigh*


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Adventures with C++
Date: 17 May 2013 13:22:33
Message: <51966759$1@news.povray.org>
On 16/05/2013 06:46 PM, Orchid Win7 v1 wrote:
> I can still hardly believe that this whole improbable contraption
> actually ended up WORKING in the end! o_O

The daft thing is, it turns out to actually be pretty easy to write some 
C++, make a DLL out of it, and call that from C#. The actual code that 
ended up in source control is both small and simple.

This belies the vast amount of man-hours it took to *arrive* at this 
final arrangement. It took an absurd amount of Google searches and 
trail-and-error to get the myriad of pieces to fit together just right.

In summary, it's easy when you know how. So easy, presumably, that 
nobody bothers to write down how it's actually done - so the next person 
who tries to do this will have the exact same problem. :-/


Post a reply to this message

From: Warp
Subject: Re: An actual C++ question
Date: 17 May 2013 14:16:01
Message: <519673e1@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
> Second, it seems this "feature" only exists in C++11. I don't know what 
> GCC is defaulting to, but apparently you have to add a switch to tell it 
> to accept C++11. And when I do that, my code compiles perfectly, but the 
> rest of the codebase breaks spectacularly.

> So, in summary, I had to revert everything back to how it was. *sigh*

You could use std::auto_ptr instead of std::shared_ptr, but then you'd
better disable copying for your class.

-- 
                                                          - Warp


Post a reply to this message

From: Kevin Wampler
Subject: Re: An actual C++ question
Date: 17 May 2013 21:08:03
Message: <5196d473$1@news.povray.org>
On 5/17/2013 11:16 AM, Warp wrote:
> Orchid Win7 v1 <voi### [at] devnull> wrote:
>> Second, it seems this "feature" only exists in C++11. I don't know what
>> GCC is defaulting to, but apparently you have to add a switch to tell it
>> to accept C++11. And when I do that, my code compiles perfectly, but the
>> rest of the codebase breaks spectacularly.
>
>> So, in summary, I had to revert everything back to how it was. *sigh*
>
> You could use std::auto_ptr instead of std::shared_ptr, but then you'd
> better disable copying for your class.
>

Or use boost::shared_ptr of course.

Actually, this reminds me that I should update some of my own code from 
boost:shared_ptr to std::shared_ptr.


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: An actual C++ question
Date: 20 May 2013 13:44:11
Message: <519a60eb$1@news.povray.org>
On 15/05/2013 10:44 PM, Warp wrote:
> Orchid Win7 v1<voi### [at] devnull>  wrote:
>> So I have to put the entire class definition into the header file. But
>> that means I have to put Secrets into the header file too - a data
>> structure that clients have absolutely no reason to know anything about.
>
> If having the internal-implementation-detail as a member variable of
> the class is something you just must avoid, and especially if this is
> a class that doesn't get instantiated a lot, then the solution is to
> use the Pimpl idiom, which regardless of the funny name, is exactly what
> you described. In other words, make a forward declaration of that private
> class and just have a pointer to it as member.

My next question was going to be "is there a way to expose part of a 
class so that the test framework can access it, but nothing else can?"

And then I read the documentation for our test framework [GTest, in case 
anybody cares], and it says to do basically the same thing as the above. 
IOW, make a private class, put it in its own header file, let the test 
framework include that header file, but nobody else.

Not sure if it's worth it just to hide one single method, but it might 
be useful in other parts of the codebase...


Post a reply to this message

From: Warp
Subject: Re: An actual C++ question
Date: 20 May 2013 16:15:34
Message: <519a8465@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
> And then I read the documentation for our test framework [GTest, in case 
> anybody cares], and it says to do basically the same thing as the above. 
> IOW, make a private class, put it in its own header file, let the test 
> framework include that header file, but nobody else.

In principle if a class or function exists in a namespace that's not
local to a compilation unit (in other words, a nameless namespace inside
a compilation unit), it will be visible globally and could therefore
technically speaking be used by everything else.

Unlike it might seem, header files in C/C++ are not a language feature.
They are not syntax that imposes some kind of semantics (eg. access
restrictions or something like that.) It's not like other code couldn't
use some class or function if it doesn't have access to the header file
that declares them.

Header files are both a convenience and an abstraction tool, but are
strictly speaking unnecessary.

Let's say that you *know* that somewhere in the innards of some compilation
unit (which might be eg. a library) there's a function named 'foo' which
takes an int and returns an int, which is in the global namespace. Even
if you have no access to any header that declares said function, you can
still just write in your own code:

//----------------------------------------------------------------
int foo(int);

void myFunction()
{
    foo(5);
}
//----------------------------------------------------------------

With classes it becomes a bit more complicated because you need to
know the exact contents of the class. However, technically speaking
if you know that you don't need any header file to use it.

Of course all this is mostly theoretical.

-- 
                                                          - Warp


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: An actual C++ question
Date: 21 May 2013 13:25:32
Message: <519bae0c$1@news.povray.org>
>>> So, in summary, I had to revert everything back to how it was. *sigh*
>>
>> You could use std::auto_ptr instead of std::shared_ptr, but then you'd
>> better disable copying for your class.
>
> Or use boost::shared_ptr of course.

OK, so I went with boost::shared_ptr in the end.

However, I can't seem to figure out what to write in the constructor. 
I've got a field that looks like

   boost::shared_ptr<std::vector<Foo>> _foo;

What do I need to do to initialise this correctly?


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: An actual C++ question
Date: 21 May 2013 13:27:09
Message: <519bae6d@news.povray.org>
On 20/05/2013 09:15 PM, Warp wrote:
> Of course all this is mostly theoretical.

Yeah. Assuming that my fellow coders aren't *purposely* trying to break 
things, I just want to structure the code I'm writing in a way which 
minimises the potential for mistakes, that's all.

(We've got some code which is only public so that the test suite can 
run. It makes me feel slightly twitchy, but hey...)


Post a reply to this message

From: Kevin Wampler
Subject: Re: An actual C++ question
Date: 21 May 2013 13:32:36
Message: <519bafb4$1@news.povray.org>
On 5/21/2013 10:25 AM, Orchid Win7 v1 wrote:
> However, I can't seem to figure out what to write in the constructor.
> I've got a field that looks like
>
>    boost::shared_ptr<std::vector<Foo>> _foo;
>
> What do I need to do to initialise this correctly?


boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());

Take a look over the constructors of shared_ptr for more detail.  I 
should note that it's relatively uncommon that I want a shared_ptr to a 
std::vector.  Unless you actually need to store _foo somewhere else in 
the code it's might be better to just forgo the shared_ptr and pass _foo 
by reference to whichever functions need it.


Post a reply to this message

From: Kevin Wampler
Subject: Re: An actual C++ question
Date: 21 May 2013 13:38:00
Message: <519bb0f8@news.povray.org>
On 5/21/2013 10:32 AM, Kevin Wampler wrote:
> On 5/21/2013 10:25 AM, Orchid Win7 v1 wrote:
>> However, I can't seem to figure out what to write in the constructor.
>> I've got a field that looks like
>>
>>    boost::shared_ptr<std::vector<Foo>> _foo;
>>
>> What do I need to do to initialise this correctly?
>
>
> boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());
>

Oh, and it's probably best to write it like this:

boost::shared_ptr<std::vector<Foo> > _foo(new std::vector<Foo>());

Since some compilers will complain about using >> in a type definition 
(due to the ambiguity with the >> operator).


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: An actual C++ question
Date: 21 May 2013 17:07:09
Message: <519be1fd$1@news.povray.org>
On 21/05/2013 06:32 PM, Kevin Wampler wrote:
> On 5/21/2013 10:25 AM, Orchid Win7 v1 wrote:
>> However, I can't seem to figure out what to write in the constructor.
>> I've got a field that looks like
>>
>> boost::shared_ptr<std::vector<Foo>> _foo;
>>
>> What do I need to do to initialise this correctly?
>
>
> boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());
>
> Take a look over the constructors of shared_ptr for more detail. I
> should note that it's relatively uncommon that I want a shared_ptr to a
> std::vector. Unless you actually need to store _foo somewhere else in
> the code it's might be better to just forgo the shared_ptr and pass _foo
> by reference to whichever functions need it.

The only reason I'm doing this is to avoid putting the real definition 
of Foo in the header file.


Post a reply to this message

From: Warp
Subject: Re: An actual C++ question
Date: 22 May 2013 15:45:58
Message: <519d2076@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
> However, I can't seem to figure out what to write in the constructor. 
> I've got a field that looks like

>    boost::shared_ptr<std::vector<Foo>> _foo;

> What do I need to do to initialise this correctly?

What do you mean by "field"? Your question is not clear enough.

(And btw, don't start names with an underscore. Those are reserved for
the compiler.)

-- 
                                                          - Warp


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: An actual C++ question
Date: 23 May 2013 03:21:03
Message: <519dc35f$1@news.povray.org>
On 22/05/2013 08:45 PM, Warp wrote:
> Orchid Win7 v1<voi### [at] devnull>  wrote:
>> However, I can't seem to figure out what to write in the constructor.
>> I've got a field that looks like
>
>>     boost::shared_ptr<std::vector<Foo>>  _foo;
>
>> What do I need to do to initialise this correctly?
>
> What do you mean by "field"? Your question is not clear enough.

I mean something like

   class Foobar
   {
     private:
       boost::shared_ptr<std::vector<Foo>> foo;
     public:
       Foobar()
   }

> (And btw, don't start names with an underscore. Those are reserved for
> the compiler.)

Hoooookay... In that case, there's about 200 lines in the existing 
codebase that need to be changed. o_O


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: An actual C++ question
Date: 23 May 2013 03:22:34
Message: <519dc3ba$1@news.povray.org>
>> boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());
>
> Oh, and it's probably best to write it like this:
>
> boost::shared_ptr<std::vector<Foo> > _foo(new std::vector<Foo>());
>
> Since some compilers will complain about using >> in a type definition
> (due to the ambiguity with the >> operator).

VisualStudio compiles this perfectly. GCC point-blank fails to compile 
it. *sigh* Gotta love the number of inconsistencies between two 
compilers for supposedly "the same" language...

(VC emits endless warnings about "printf may be unsafe; please use 
printf_s instead". Apparently the latter function doesn't exist in GCC...)


Post a reply to this message

From: Francois Labreque
Subject: Re: An actual C++ question
Date: 23 May 2013 09:26:48
Message: <519e1918@news.povray.org>
Le 2013-05-23 03:22, Orchid Win7 v1 a écrit :
>>> boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());
>>
>> Oh, and it's probably best to write it like this:
>>
>> boost::shared_ptr<std::vector<Foo> > _foo(new std::vector<Foo>());
>>
>> Since some compilers will complain about using >> in a type definition
>> (due to the ambiguity with the >> operator).
>
> VisualStudio compiles this perfectly. GCC point-blank fails to compile
> it. *sigh* Gotta love the number of inconsistencies between two
> compilers for supposedly "the same" language...

You are surprised that a Microsoft product allows something that is 
frowned upon by a more anal-retentive competitor?!?

>
> (VC emits endless warnings about "printf may be unsafe; please use
> printf_s instead". Apparently the latter function doesn't exist in GCC...)

They are MS-specific versions of the functions.

http://msdn.microsoft.com/en-us/library/8ef0s5kh%28v=vs.80%29.aspx
http://msdn.microsoft.com/en-us/library/239ffwa0%28v=vs.80%29.aspx

I'm sure the purists would frown that Microsoft decides to mess with 
<sdtio.h> instead of putting them in a "msstdio.h" or similar.  Way back 
when the dinosaurs still roamed the Earth, I used to hang in comp.lang.c 
and I vividly remember certain members being quite angry at Borland for 
pretending that conio.h was part of the standard headers and its 
functions part of the standard libraries.



-- 
/*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: Kevin Wampler
Subject: Re: An actual C++ question
Date: 23 May 2013 10:11:01
Message: <519e2375$1@news.povray.org>
On 5/23/2013 6:27 AM, Francois Labreque wrote:
> Le 2013-05-23 03:22, Orchid Win7 v1 a écrit :
>>>> boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());
>>>
>>> Oh, and it's probably best to write it like this:
>>>
>>> boost::shared_ptr<std::vector<Foo> > _foo(new std::vector<Foo>());
>>>
>>> Since some compilers will complain about using >> in a type definition
>>> (due to the ambiguity with the >> operator).
>>
>> VisualStudio compiles this perfectly. GCC point-blank fails to compile
>> it. *sigh* Gotta love the number of inconsistencies between two
>> compilers for supposedly "the same" language...
>
> You are surprised that a Microsoft product allows something that is
> frowned upon by a more anal-retentive competitor?!?
>

Actually, I'm a little surprised that GCC didn't accept it, as that sort 
of things should be allowed under the C++11 standard 
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html) and 
GCC 4.7 is listed as supporting that feature 
(http://gcc.gnu.org/gcc-4.7/cxx0x_status.html).  In general GCC seems to 
have much better C++11 support that MSVC, so it's strange to see an 
example of the opposite -- perhaps Andrew's using an old version of GCC 
or something.


Post a reply to this message

From: scott
Subject: Re: An actual C++ question
Date: 23 May 2013 10:14:06
Message: <519e242e$1@news.povray.org>
>>> boost::shared_ptr<std::vector<Foo> > _foo(new std::vector<Foo>());
>>>
>>> Since some compilers will complain about using >> in a type definition
>>> (due to the ambiguity with the >> operator).
>>
>> VisualStudio compiles this perfectly. GCC point-blank fails to compile
>> it. *sigh* Gotta love the number of inconsistencies between two
>> compilers for supposedly "the same" language...
>
> You are surprised that a Microsoft product allows something that is
> frowned upon by a more anal-retentive competitor?!?

boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());

I don't see how the >> is ambiguous at all in this statement. Seems to 
me like lazy/bad parser design if this trips it up.


Post a reply to this message

From: Kevin Wampler
Subject: Re: An actual C++ question
Date: 23 May 2013 10:44:39
Message: <519e2b57$1@news.povray.org>
On 5/23/2013 7:14 AM, scott wrote:
>
> boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());
>
> I don't see how the >> is ambiguous at all in this statement. Seems to
> me like lazy/bad parser design if this trips it up.
>

It's not quite so cut and dry as you might guess.  For example:


#include <iostream>
using std::cout;
using std::endl;

int _foo(int i) {
	return i;
}

namespace std {
	static const int vector = 7;
}

namespace boost {
	static const int shared_ptr = 5;
}

int main(int argc, char** argv) {
	int Foo = 3;
	cout << (boost::shared_ptr<std::vector<Foo>> _foo(NULL)) << endl;
	return 0;
}


If you run this program it should print "1" (at least in MSVC), which is 
the result of treating < and >> and the less-than and bit-shift 
operators.  Of course you couldn't write "new std::vector<Foo>()" in 
this scheme, but it does show that it's hard to tell what's a template 
and what's not at a purely syntatic level.

In any case, the C++11 standard does allow 
"boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>()); " and 
the most recent version of GCC supposedly supports this.  You can read a 
bit more about it here: 
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html


Post a reply to this message

From: Warp
Subject: Re: An actual C++ question
Date: 23 May 2013 11:38:28
Message: <519e37f3@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
> > What do you mean by "field"? Your question is not clear enough.

> I mean something like

>    class Foobar
>    {
>      private:
>        boost::shared_ptr<std::vector<Foo>> foo;
>      public:
>        Foobar()
>    }

Why didn't you say so in the first place?

If you want to initialize that member function in the constructor, use
the constructor's initializer list or just assign to it in the contructor's
body. In the first case:

    Foobar::Foobar(): foo(new std::vector<Foo>)
    {}

Or if you prefer,

    Foobar::Foobar()
    {
        foo = new std::vector<Foo>;
    }

Btw, C++98 does not support >> for closing a double template. You have
to add a space in between.

I'm wondering why you are using a std::vector, though. I thought that what
you wanted was something like this:

//----------------------------------------------------------------

class Foobar
{
    struct Impl;
    boost::shared_ptr<Impl> impl;

 public:
    Foobar();
};
//----------------------------------------------------------------

In which case the implementation would be like:

//----------------------------------------------------------------
struct Foobar::Impl
{
    std::vector<Foo> array;
}

Foobar::Foobar(): impl(new Impl)
{}
//----------------------------------------------------------------

Much simpler and cleaner that way.

> > (And btw, don't start names with an underscore. Those are reserved for
> > the compiler.)

> Hoooookay... In that case, there's about 200 lines in the existing 
> codebase that need to be changed. o_O

I have never quite understood why so many programmers seem to be obsessed
with putting underscores at the beginning of names.

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: An actual C++ question
Date: 23 May 2013 11:41:32
Message: <519e38ac@news.povray.org>
Kevin Wampler <nob### [at] nowherenet> wrote:
> On 5/21/2013 10:25 AM, Orchid Win7 v1 wrote:
> > However, I can't seem to figure out what to write in the constructor.
> > I've got a field that looks like
> >
> >    boost::shared_ptr<std::vector<Foo>> _foo;
> >
> > What do I need to do to initialise this correctly?

> boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());

*Where* are you doing that?

If you mean it like this:

class Foobar
{
    boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());
};

then it works, but only in C++11. I think Andrew needed to do it in C++98.

-- 
                                                          - Warp


Post a reply to this message

From: scott
Subject: Re: An actual C++ question
Date: 23 May 2013 11:58:47
Message: <519e3cb7$1@news.povray.org>
>> boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());
>>
>> I don't see how the >> is ambiguous at all in this statement. Seems to
>> me like lazy/bad parser design if this trips it up.
>
> It's not quite so cut and dry as you might guess.  For example:
...
>      cout << (boost::shared_ptr<std::vector<Foo>> _foo(NULL)) << endl;

Is that ambiguous?


Post a reply to this message

From: Kevin Wampler
Subject: Re: An actual C++ question
Date: 23 May 2013 12:29:11
Message: <519e43d7@news.povray.org>
On 5/23/2013 8:58 AM, scott wrote:
>>> boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());
>>>
>>> I don't see how the >> is ambiguous at all in this statement. Seems to
>>> me like lazy/bad parser design if this trips it up.
>>
>> It's not quite so cut and dry as you might guess.  For example:
> ...
>>      cout << (boost::shared_ptr<std::vector<Foo>> _foo(NULL)) << endl;
>
> Is that ambiguous?
>


Obviously not since it compiles.  It is, however, ambiguous unless you 
know the types of boost::shared_ptr and std::vector (and you need to 
know them during lexical analysis).  I wasn't saying that it's 
impossible to correctly parse this sort of thing, just that correctly 
parsing it is a more non-trivial task than it might at first appear.


Post a reply to this message

From: Kevin Wampler
Subject: Re: An actual C++ question
Date: 23 May 2013 12:31:15
Message: <519e4453@news.povray.org>
On 5/23/2013 8:41 AM, Warp wrote:
> Kevin Wampler <nob### [at] nowherenet> wrote:
>> On 5/21/2013 10:25 AM, Orchid Win7 v1 wrote:
>>> However, I can't seem to figure out what to write in the constructor.
>>> I've got a field that looks like
>>>
>>>     boost::shared_ptr<std::vector<Foo>> _foo;
>>>
>>> What do I need to do to initialise this correctly?
>
>> boost::shared_ptr<std::vector<Foo>> _foo(new std::vector<Foo>());
>
> *Where* are you doing that?
>

I was just giving him an example to point out that you pass a raw 
pointer to the constructor of shared_ptr and assuming that he'd figure 
the rest out from there.  But you're right that I perhaps should have 
been more explicit.


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: An actual C++ question
Date: 23 May 2013 13:24:37
Message: <519e50d5$1@news.povray.org>
>> You are surprised that a Microsoft product allows something that is
>> frowned upon by a more anal-retentive competitor?!?
>>
>
> Actually, I'm a little surprised that GCC didn't accept it, as that sort
> of things should be allowed under the C++11 standard
> (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html) and
> GCC 4.7 is listed as supporting that feature
> (http://gcc.gnu.org/gcc-4.7/cxx0x_status.html). In general GCC seems to
> have much better C++11 support that MSVC, so it's strange to see an
> example of the opposite -- perhaps Andrew's using an old version of GCC
> or something.

[Our version of] GCC seems to require a command-line switch to enable 
C++11 support, so...


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: An actual C++ question
Date: 23 May 2013 13:28:28
Message: <519e51bc$1@news.povray.org>
On 23/05/2013 04:38 PM, Warp wrote:
> Orchid Win7 v1<voi### [at] devnull>  wrote:
>>> What do you mean by "field"? Your question is not clear enough.
>
>> I mean something like
>
>>     class Foobar
>>     {
>>       private:
>>         boost::shared_ptr<std::vector<Foo>>  foo;
>>       public:
>>         Foobar()
>>     }
>
> Why didn't you say so in the first place?
>
> If you want to initialize that member function in the constructor, use
> the constructor's initializer list or just assign to it in the contructor's
> body. In the first case:
>
>      Foobar::Foobar(): foo(new std::vector<Foo>)
>      {}
>
> Or if you prefer,
>
>      Foobar::Foobar()
>      {
>          foo = new std::vector<Foo>;
>      }

I had hoped it would "just work" the same way it does if it wasn't a 
pointer. But it appears that no, you have to make it actually point to 
something. (Which is reasonable.) The constructor seems like the most 
sensible place to do that.

> Btw, C++98 does not support>>  for closing a double template. You have
> to add a space in between.

Yeah, I already discovered that. ;-)

> I'm wondering why you are using a std::vector, though. I thought that what
> you wanted was something like this:
>
> //----------------------------------------------------------------
>
> class Foobar
> {
>      struct Impl;
>      boost::shared_ptr<Impl>  impl;
>
>   public:
>      Foobar();
> };
> //----------------------------------------------------------------
>
> In which case the implementation would be like:
>
> //----------------------------------------------------------------
> struct Foobar::Impl
> {
>      std::vector<Foo>  array;
> }
>
> Foobar::Foobar(): impl(new Impl)
> {}
> //----------------------------------------------------------------
>
> Much simpler and cleaner that way.

Ooo, interesting... Yeah, that could work.

>>> (And btw, don't start names with an underscore. Those are reserved for
>>> the compiler.)
>
>> Hoooookay... In that case, there's about 200 lines in the existing
>> codebase that need to be changed. o_O
>
> I have never quite understood why so many programmers seem to be obsessed
> with putting underscores at the beginning of names.

Apparently ReSharper insists that every C# private field begins with an 
underscore. I guess when the guys started writing C++, they just copied 
that naming convention. After all, it's only a name, right? You can name 
your stuff anything you li- oh, OK, maybe not...


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Adventures with C++
Date: 23 May 2013 13:33:12
Message: <519e52d8$1@news.povray.org>
Today, I spent about 2 hours trying to figure out why the hell all the 
tests pass when I compile in Debug mode, but two of them fail if I 
compile in Release mode.

Literally, every time I run in Debug mode, all the tests pass. It only 
fails in Release mode. In particular, that means I can't fire up the 
debugger to see why it's failing. You can only debug in Debug mode, and 
in Debug mode it works perfectly.

Apparently Google is your friend. After some minimal amount of effort, I 
came across a very well-written forum post which helpfully explains that 
in Debug mode all variables are guaranteed to be initialised to default 
values, whereas in Release mode variables take on whatever random 
gibberish happens to be in memory, unless you remember to explicitly 
initialise them to something sane.

Ouch. >_<

Now I guess I understand why Java, C#, et al make such a fuss about 
insisting on explicit initialisation and / or explicitly specifying 
default initialisation rules...



The other fun thing is that C++ allows you to "throw" absolutely 
anything. Several places in the code throw std::string, presumably in 
the hope that this will result in some helpful error message being printed.

It doesn't. ;-)


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: An actual C++ question
Date: 23 May 2013 13:34:58
Message: <519e5342$1@news.povray.org>
> [Our version of] GCC seems to require a command-line switch to enable
> C++11 support, so...

In other news, I may have found out why turning this on breaks GTest. 
Apparently it's somehow related to a late change to the C++11 spec. 
Basically VC doesn't support some feature that got added to the standard 
late. (Varadic tuples or something.) That doesn't completely explain why 
it compiles just fine without C++11 turned on though...


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Adventures with C++
Date: 23 May 2013 13:40:14
Message: <519e547e$1@news.povray.org>
The OTHER fun thing, of course, is when you invoke a template with the 
wrong parameters.

Trouble is, the compiler has no idea that the parameters are wrong. All 
it knows is that when it tries to expand the template, somewhere several 
million miles away from your code a type mismatch happens, or an 
operator doesn't exist, or...

This would be acceptable if VC offered some how to find out WHAT 
TEMPLATE it was attempting to expand when the error occurred. But no, it 
just shows you the source code for the STL (or Boost or whatever) and 
points at the line on which the problem was actually detected. There 
seems to be no way that I can discover what line of which file resulting 
in this template being invoked in the first place - and THAT is surely 
where the problem is, not in STL itself.

(E.g., today I erroneously said set<string, string>. It took quite a 
while to hunt through the source control history to manually inspect 
every template instruction I've recently touched and thus discover the 
problem. If I knew, say, WHAT FILE to look in, it might be faster...)


Post a reply to this message

Goto Latest 50 Messages Next 15 Messages >>>

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