Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

Avenging Dentist posted:

:words:

Goddamn you're needlessly a prick.

I have this question because I've done the exact same thing with the CString in MFC (which does use templates, exactly for the reason I talked about) and haven't run into this problem. OMG I HAVE A STRING LITERAL IN MY CODE JESUS WHAT WILL I DO?

const CString OhGodYouInternetPosters(_T("You piss me off so much you stupid newbie programmers who have questions about books"));

Thanks for all the help though, you self-satisfied and condescending oval office.

Adbot
ADBOT LOVES YOU

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Plastic Jesus posted:

I have this question because I've done the exact same thing with the CString in MFC (which does use templates, exactly for the reason I talked about) and haven't run into this problem.

Then you got lucky because CString has exactly the same limitations in this case as std::string (yes, I just tested it).

You come in here, ask a question, get useful answers to your question, including the idiomatic solution to your problem, and then get pissy because the answer isn't what you want.

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

Plastic Jesus posted:

This is an extremely easy (and "effective" even) thing to do at the class level, I'm just wondering if it's something that can only be done within a class.
It can't be done at all within a class. Non-integral constants cannot be defined inside of a class declaration:

http://codepad.org/bR7Dd35d
http://codepad.org/XRI8ak5I

It has to be defined once: http://codepad.org/xJNWHRcq

(Mostly) Similarly, in a namespace, you declare the globals as extern and define them in one file and make sure your globals don't depend on each other, or you wrap the globals inside of functions like this
code:
const std::string& global(){
  static std::string _ = "Yo";
  return _;
}
// or
const blahblah{
  static std::string *_ = new std::string("Yo");
  return *_;
}
and declare it in a header file like any other function.

quote:

Calling a function isn't really a solution to this problem.
Function calls are cheap until proven guilty.

edit: bustin' caps in tables

Mustach fucked around with this message at 01:10 on Apr 3, 2009

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Mustach posted:

(Mostly) Similarly, in a namespace, you declare the globals as extern and define them in one file and make sure your globals don't depend on each other, or you wrap the globals inside of functions like this

Standard threading caveats apply, of course (not that it matters when you're doing static initialization).

Incidentally, because of how MSVC links projects, things will "work" if the object is defined in a translation unit that is alphabetically before where it's used (assuming external linkage, etc). You can obviously do similar stuff in gcc, but this is also probably the brittlest thing you do.

narfanator
Dec 16, 2008

Mustach posted:

code:
const std::string& global(){
  static std::string _ = "Yo";
  return _;
}
// or
const blahblah{
  static std::string *_ = new std::string("Yo");
  return *_;
}
and declare it in a header file like any other function.

Function calls are cheap until proven guilty.

Huh. Neat, never thought of using a simple function in place of a global variable. Are there any problems with making it an inline function, and is there a reason you're not just returning the output of new? Can you mention some unexpected benefits of this method? Kinda curious.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

narfanator posted:

Huh. Neat, never thought of using a simple function in place of a global variable. Are there any problems with making it an inline function, and is there a reason you're not just returning the output of new? Can you mention some unexpected benefits of this method? Kinda curious.

Inline is preferred. If by "returning the output of new", you mean something like this:
code:
const foo & get_global()
{
    return *(new foo);
}
that's bad because it creates a new foo every time you call get_global. The static keyword means that that initialization will only happen the first time you call the function. Every time after that, only the return statement is called.

Cidrick
Jun 10, 2001

Praise the siamese

Plastic Jesus posted:

Goddamn you're needlessly a prick.

I have this question because I've done the exact same thing with the CString in MFC (which does use templates, exactly for the reason I talked about) and haven't run into this problem. OMG I HAVE A STRING LITERAL IN MY CODE JESUS WHAT WILL I DO?

const CString OhGodYouInternetPosters(_T("You piss me off so much you stupid newbie programmers who have questions about books"));

Thanks for all the help though, you self-satisfied and condescending oval office.

Avenging Dentist posted:

Then you got lucky because CString has exactly the same limitations in this case as std::string (yes, I just tested it).

You come in here, ask a question, get useful answers to your question, including the idiomatic solution to your problem, and then get pissy because the answer isn't what you want.

Shut the fuuuuck up or take it to PM

THANKS

floWenoL
Oct 23, 2002

Plastic Jesus posted:

Doing cost char* is just so ugly.

It is, but what does that have to do with AD's suggestion to use a const char[]? (Hint: arrays are not pointers.)

narfanator
Dec 16, 2008

Avenging Dentist posted:

Inline is preferred. If by "returning the output of new", you mean something like this:
code:
const foo & get_global()
{
    return *(new foo);
}
that's bad because it creates a new foo every time you call get_global. The static keyword means that that initialization will only happen the first time you call the function. Every time after that, only the return statement is called.

Oh, duh.

Is there something horrible I'm not realizing about making a templated makeOrGetGlobal() function? It seems like it might make a lot of sense, or be boneheaded.
code:
template<class T>
T makeOrGetGlobal()
{
  static T _ = new T()
  return _;
}

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

narfanator posted:

code:
template<class T>
T makeOrGetGlobal()
{
  static T _ = new T()
  return _;
}

That's not gonna compile. Aside from the lack of semicolon after the new, you're assigning a pointer to a value-type.

Even if it did compile, it's probably not what you want. The return type means you'll be making a copy on return. It also assumes you only want one of a given type, and that that type is default-constructible. Using a pointer doesn't really get you anything except for causing the destructor not to be called (and a memory leak on lovely OSes). It's not thread-safe either. static inside a function is something that should make you worried. About the best you're going to get is something like this:

code:
template<typename T,int Tag>
T & get_global()
{
    static T _;
    return _;
}

// Usage
const int GEORGE_BUSHS_BUTT = 1;
butt &b = get_global<butt,GEORGE_BUSHS_BUTT>();
In short, it's not something I'd recommend in general.

Avenging Dentist fucked around with this message at 07:20 on Apr 3, 2009

narfanator
Dec 16, 2008

Avenging Dentist posted:

That's not gonna compile. Aside from the lack of semicolon after the new, you're assigning a pointer to a value-type.

Even if it did compile, it's probably not what you want. The return type means you'll be making a copy on return. It also assumes you only want one of a given type, and that that type is default-constructible. Using a pointer doesn't really get you anything except for causing the destructor not to be called (and a memory leak on lovely OSes). It's not thread-safe either. static inside a function is something that should make you worried. About the best you're going to get is something like this:

code:
template<typename T,int Tag>
T & get_global()
{
    static T _;
    return _;
}

// Usage
const int GEORGE_BUSHS_BUTT = 1;
butt &b = get_global<butt,GEORGE_BUSHS_BUTT>();
In short, it's not something I'd recommend in general.

Yeah; you're very right about not wanting it that way. I was thinking "pointer", but didn't code it that way. Or code carefully, at all.

It seems like the only, ever, appropriate time to use that structure is when you have a huge amount of singletons / globals, and either had a solution for the memory leak aspect, or didn't care, and wanted a quick way to manage/access them. Or, rather, wanted a way to use them that didn't take any management work.
(It seems like making a garbage collector specifically for all of the things, and only those things, that that function makes wouldn't be that bad, but I don't know what I'm talking about.)

Correct me if I'm wrong, but if you make that function (the pointer version) inline, it pretty much optimizes out at compile time to the same as having a global pointer? And, correct me if I'm wrong, but that's one of those "newbie worthless optimizations" you mentioned?

Hmm... Is there a way to declare a class or function in a header, such that only that header actually has access to it? (Templated things need to have their defs in the header, but if I have templated things that access a manager no-one else needs to see, I'd like to hide the manager if possible)

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

narfanator posted:

It seems like the only, ever, appropriate time to use that structure is when you have a huge amount of singletons / globals, and either had a solution for the memory leak aspect, or didn't care, and wanted a quick way to manage/access them.

Using a value-type (i.e. not a pointer) resolves the memory leak. This really should only be used to resolve static initialization order problems. It's thread-safe to initialize these functions before main starts (because the process is single-threaded then), but not after, unless your app is single-threaded anyway.

This is just not a good thing to do in general. If you need a global, use a global. If you need a singleton (which is occasionally different), use a singleton. If you need lots of singletons, make a generic singleton that you specialize. All this does is make global access more convoluted and bug-prone.

narfanator posted:

Correct me if I'm wrong, but if you make that function (the pointer version) inline, it pretty much optimizes out at compile time to the same as having a global pointer? And, correct me if I'm wrong, but that's one of those "newbie worthless optimizations" you mentioned?

If a micro-optimization takes 7 characters to type, by all means do it, but it's pointless to spend more than a few minutes savagely micro-optimizing, you're wasting your time, as well as the time of people who have to maintain your code later on.

narfanator posted:

Hmm... Is there a way to declare a class or function in a header, such that only that header actually has access to it? (Templated things need to have their defs in the header, but if I have templated things that access a manager no-one else needs to see, I'd like to hide the manager if possible)

No, because headers are not compiled, so from a compiler's perspective, they don't "see" anything at all. They are textually included in .cpp files (translation units). I just put a pair of underscores after any identifiers I don't want people using.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

narfanator posted:

Correct me if I'm wrong, but if you make that function (the pointer version) inline, it pretty much optimizes out at compile time to the same as having a global pointer?

It's not legal under C99.
6.7.4.3. An inline definition of a function with external linkage shall not contain a definition of a modifiable object with static storage duration, and shall not contain a reference to an identifier with internal linkage.
I haven't checked whether C++ gives different semantics to it.

quote:

Hmm... Is there a way to declare a class or function in a header, such that only that header actually has access to it? (Templated things need to have their defs in the header, but if I have templated things that access a manager no-one else needs to see, I'd like to hide the manager if possible)

Make the templated function a friend of the manager class, or declare the manager class without a definition and pass around opaque pointers to it, or curse Bjarne Stroustrup for not giving C++ a module system.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

rjmccall posted:

Make the templated function a friend of the manager class, or declare the manager class without a definition and pass around opaque pointers to it, or curse Bjarne Stroustrup for not giving C++ a module system.

While there have been proposals for modules, the combination of templates and modules is just going to be a clusterfuck. Hopefully, they'll at least learn from the export debacle.

P.S. inline functions with static local variables are legal:

ISO/IEC 14882:2003 §7.1.2 #4 posted:

A static local variable in an extern inline function always refers to the same object. A string literal in an extern inline function is the same object in different translation units.

Avenging Dentist fucked around with this message at 08:13 on Apr 3, 2009

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Avenging Dentist posted:

While there have been proposals for modules, the combination of templates and modules is just going to be a clusterfuck. Hopefully, they'll at least learn from the export debacle.

Templates are already a clusterfuck.

I think you could do C++ modules pretty straightforwardly if you used a rule like only those template specializations defined by modules directly imported by a module shall be considered, but I may be neglecting something. At any rate, I do not think C++ needs more language features.

EDIT: Oh, that's exciting. I suppose it's just more unique-definition work for the linker.

rjmccall fucked around with this message at 08:25 on Apr 3, 2009

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

rjmccall posted:

At any rate, I do not think C++ needs more language features.

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

Avenging Dentist posted:

It's not thread-safe either.
Good link. After posting, I wondered whether or not any implementations make (or were even allowed to make) the static stuff thread-safe.

edit: actually, there's some discussion with Chen in the comments and "But TC1 changed that and now re-entrancy during static initialization has been declared "undefined"."

Mustach fucked around with this message at 14:52 on Apr 3, 2009

Mach Won
Jun 17, 2004

Is UNC playing? My post is either whining about (1) ref favoritism, (2) unfair recruiting/player caliber, (3) opposing team sucking or (4) the inevitable UNC win. The day you see me giving UNC credit for anything is the day someone hacked my account.

Roy era: 1-16 :qq: RIVALS!!!!!
Hey guys, I have a short question that I'm sure has an obvious answer, but since this my first time working with the STL, I just don't know the answer.

What's wrong with this exactly?

code:
vector<string> *pathXY = new vector<string>;
vector<string>::iterator pathXY_it;

...

for(pathXY_it = pathXY.begin(); pathXY_it < pathXY.end(); pathXY_it++) //<--- ERROR
        cout << *pathXY_it << endl;
My compiler says:

error: request for member `begin' in `pathXY', which is of non-class type `std::vector<std::string, std::allocator<std::string> >*

I guess it has something to do with trying to use the iterator to the vector<string> that pathXY points to, but I don't know how to correct it.

That Turkey Story
Mar 30, 2003

Mach Won posted:

My compiler says:

error: request for member `begin' in `pathXY', which is of non-class type `std::vector<std::string, std::allocator<std::string> >*

That basically says it all. You tried to use ".begin" on a pointer. Use -> instead, although I question why you are dynamically allocating the vector in your example to begin with.

Mach Won
Jun 17, 2004

Is UNC playing? My post is either whining about (1) ref favoritism, (2) unfair recruiting/player caliber, (3) opposing team sucking or (4) the inevitable UNC win. The day you see me giving UNC credit for anything is the day someone hacked my account.

Roy era: 1-16 :qq: RIVALS!!!!!
Duh, I knew it was obvious. I'm using the dynamic allocation in this code because it'll be used in a larger program, and it'd be nice to change as little as possible.

Thanks for the help!

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Mach Won posted:

Duh, I knew it was obvious. I'm using the dynamic allocation in this code because it'll be used in a larger program, and it'd be nice to change as little as possible.

Thanks for the help!

Don't try to preemptively make your code generic. It'll just make things a mess.

floWenoL
Oct 23, 2002

Mach Won posted:

Duh, I knew it was obvious. I'm using the dynamic allocation in this code because it'll be used in a larger program, and it'd be nice to change as little as possible.

I don't understand why you think using dynamic allocation correlates to being used in a larger program.

Zakalwe
May 12, 2002

Wanted For:
  • Terrorism
  • Kidnapping
  • Poor Taste
  • Unlawful Carnal Gopher Knowledge
Also, if at all possible you should get into the habit of using const_iterator and also preincrementing the iterator instead of postincrementing it in the for loop

Mach Won
Jun 17, 2004

Is UNC playing? My post is either whining about (1) ref favoritism, (2) unfair recruiting/player caliber, (3) opposing team sucking or (4) the inevitable UNC win. The day you see me giving UNC credit for anything is the day someone hacked my account.

Roy era: 1-16 :qq: RIVALS!!!!!

floWenoL posted:

I don't understand why you think using dynamic allocation correlates to being used in a larger program.

It will in my case because I will have to deal with an unknown number of paths. I realize that it has nothing to do with "larger programs."

quote:

Also, if at all possible you should get into the habit of using const_iterator and also preincrementing the iterator instead of postincrementing it in the for loop

I'll look into both of these.

I'm sure I'll be posting more tomorrow, I've got a project due Monday and my C++ is really rusty!

floWenoL
Oct 23, 2002

Mach Won posted:

It will in my case because I will have to deal with an unknown number of paths. I realize that it has nothing to do with "larger programs."

Still, that has nothing to do with dynamic allocation.

newsomnuke
Feb 25, 2007

Surely having lots of paths is more a reason not to use dynamic memory, as it's more likely you'll forget to delete it. Or did you mean something different?

Mach Won
Jun 17, 2004

Is UNC playing? My post is either whining about (1) ref favoritism, (2) unfair recruiting/player caliber, (3) opposing team sucking or (4) the inevitable UNC win. The day you see me giving UNC credit for anything is the day someone hacked my account.

Roy era: 1-16 :qq: RIVALS!!!!!
Well, if I don't know the number paths at runtime, and I shouldn't use dynamic memory to handle them, what should I do?

I ask because I'd genuinely like to develop good programming practices and habits.

newsomnuke
Feb 25, 2007

Mach Won posted:

Well, if I don't know the number paths at runtime, and I shouldn't use dynamic memory to handle them, what should I do?
Oh, that's what you meant by 'path', I thought you were talking about code paths. You could use a std::vector of paths, but dynamically allocating is OK IMO.

That Turkey Story
Mar 30, 2003

Mach Won posted:

Well, if I don't know the number paths at runtime, and I shouldn't use dynamic memory to handle them, what should I do?

That's exactly what containers are for. Use a vector or a list or a deque or whatever fits your problem best. Raw dynamic memory allocation is probably not what you want.

The Red Baron
Jan 10, 2005

Anyone have any idea what Alexandrescu's BoostCon "Iterators must go" keynote will refer to? I'm assuming it's about ranges, but I don't really have any experience with those so I can't tell for sure.

That Turkey Story
Mar 30, 2003

The Red Baron posted:

Anyone have any idea what Alexandrescu's BoostCon "Iterators must go" keynote will refer to? I'm assuming it's about ranges, but I don't really have any experience with those so I can't tell for sure.

Ha, I was wondering the same exact thing and came to the same conclusion as you, but I honestly don't know. I'm sure it's titled that specifically to spark controversy. Are you attending this year?

Zakalwe
May 12, 2002

Wanted For:
  • Terrorism
  • Kidnapping
  • Poor Taste
  • Unlawful Carnal Gopher Knowledge
Bah, that's a perfect opportunity to write a "considered harmful" wasted.

Also yeah iterators can be annoying. Oh look it's a pointer, but it's not really. Hooray.

&*it is a pain to have to explain.

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
"Considered harmful" is the gayest phrase to ever happen to tech writing.

The Red Baron
Jan 10, 2005

That Turkey Story posted:

Ha, I was wondering the same exact thing and came to the same conclusion as you, but I honestly don't know. I'm sure it's titled that specifically to spark controversy. Are you attending this year?
Afraid not, no time or money :(. I believe I saw some discussions on the boost dev list about filming the lectures and uploading them, something that will hopefully go beyond just being discussed. At least getting some of the "core" lectures recorded, such as David Abrahams' Boost++0x talks would be very nice.

king_kilr
May 25, 2007

Mustach posted:

"Considered harmful" is the gayest phrase to ever happen to tech writing.

Read the original Dijkstra paper.

That Turkey Story
Mar 30, 2003

The Red Baron posted:

Afraid not, no time or money :(. I believe I saw some discussions on the boost dev list about filming the lectures and uploading them, something that will hopefully go beyond just being discussed. At least getting some of the "core" lectures recorded, such as David Abrahams' Boost++0x talks would be very nice.

Yeah, I'm kind of in the same boat of no money, but I'm going anyway, after which I will be basically broke.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

king_kilr posted:

Read the original Dijkstra paper.

...which Dijkstra didn't title himself. "Considered harmful" is yet another abomination inflicted by Niklaus Wirth.

POKEMAN SAM
Jul 8, 2004

That Turkey Story posted:

Yeah, I'm kind of in the same boat of no money, but I'm going anyway, after which I will be basically broke.

Have you started looking for a new job?

That Turkey Story
Mar 30, 2003

Ugg boots posted:

Have you started looking for a new job?

Wait, do I know you? I've been putting it off, but I started updating my resume this morning and have a couple of places in mind. Registering for Boostcon immediately after getting laid off probably wasn't the smartest of ideas.

Adbot
ADBOT LOVES YOU

POKEMAN SAM
Jul 8, 2004

That Turkey Story posted:

Wait, do I know you? I've been putting it off, but I started updating my resume this morning and have a couple of places in mind. Registering for Boostcon immediately after getting laid off probably wasn't the smartest of ideas.

We talked a couple of days ago, you mentioned that you lost your job and seemed pretty bummed about it. Nothing a week of video games won't fix though, right? :)

Edit: Or you could spend your time in COBOL and make some origami versions of peoples' avatars!

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply