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
Cory Parsnipson
Nov 15, 2015

Beef posted:

Whatever the answer is, you will probably be able to post it in coding horrors. Avoid singletons in C++, but I'm sure someone forced you.

Put a break at the Poop::load line and see if it is actually executed. execute() does not depend on any state from Butt, so perhaps there is some optimization going on where gcc sees a static dispatch on a static instance and just calls get() without going by the load() in ctor.
I was not able to reproduce it though.

No one forced me. :saddowns:

I'm definitely going to refactor Poop later. Its actually a factory class so that's why it was originally a singleton. I havent decided what to do for Butt yet.

Anyway I'm gonna give it one more detailed run through with gdb and then just forget it if I don't find anything. The code's going to churn regardless as I figure out more of the design.

Adbot
ADBOT LOVES YOU

fritz
Jul 26, 2003

Cory Parsnipson posted:


code:
class Butt {
public:
	static Butt* inst();

private:
	static Butt* instance_;

	// constructors etc etc
};

A couple things stand out to me, first maybe explicitly set Butt:instance_ to nullptr instead of "whatever", second are static member fields guaranteed to be initialized in any reliable manner?

Cory Parsnipson
Nov 15, 2015
I do Butt* Butt::instance_ = nullptr in the Butt.cpp file. Is that the same thing or do you literally mean I should put = nullptr in that code snippet you highlighted?

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
Variables with static lifetime are implicitly initialized to zero anyway, I'm pretty sure.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Yep.

Cory Parsnipson
Nov 15, 2015
Ah, I think I figured it out... I simplified my example a little too much.

So there's this line of code:

code:
Butt::inst()->execute()
It should be something like this to match my actual code more closely:

code:
Butt::inst()->execute(new Poop());
And inside poop...

code:
Poop::get(std::string) {
	// Poop's map member is initialized by Butt's constructor
}

The expession "Butt::inst()", on the very first function call, will not be evaluated before "new Poop()", which I absentmindedly put all in one line.

I'm going to refactor this now... :blush:

Cory Parsnipson fucked around with this message at 09:58 on Aug 13, 2016

Xarn
Jun 26, 2015
IIRC that should be fixed in C++17 :v:

Klades
Sep 8, 2011

Cory Parsnipson posted:

code:
Butt::inst()->execute(new Poop());

Wait, why are you passing a new Poop if Poop is also a singleton?

Cory Parsnipson
Nov 15, 2015
Ah poo poo. So my actual code instantiates a different object which calls poop in its constructor. Sorry...

E: oh god this is gonna end up in coding horrors isn't it

Cory Parsnipson fucked around with this message at 23:17 on Aug 13, 2016

MrBadidea
Apr 1, 2009

Cory Parsnipson posted:

Ah poo poo. So my actual code instantiates a different object which calls poop in its constructor. Sorry...

E: oh god this is gonna end up in coding horrors isn't it

Fear not, all code belongs in the coding horrors thread :buddy:

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


This entire goddamn profession is an endless minefield of fuckups and facepalms so I wouldn't worry about it anyway :v:

Klades
Sep 8, 2011

So, here's a question. When you're writing a template class, where do you stick the implementation? I've mostly seen the implementation getting #includeed at the bottom of the header, which works, but the clang-based plugins I use in VIM really dislike it. It means I don't get any meaningful analysis on the implementation code until I compile, and my usually pleasing syntax coloring turns into a big yellow barf.
I'm tempted to just dump all the code into the header but that's messy. Is there a trick to getting this to play nice with the clang static analyzer that I'm not aware of? I know VS+ReSharper has no issues with it, so it can't be some inherent problem that can't be dealt with.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Klades posted:

So, here's a question. When you're writing a template class, where do you stick the implementation? I've mostly seen the implementation getting #includeed at the bottom of the header, which works, but the clang-based plugins I use in VIM really dislike it. It means I don't get any meaningful analysis on the implementation code until I compile, and my usually pleasing syntax coloring turns into a big yellow barf.
I'm tempted to just dump all the code into the header but that's messy. Is there a trick to getting this to play nice with the clang static analyzer that I'm not aware of? I know VS+ReSharper has no issues with it, so it can't be some inherent problem that can't be dealt with.

Yeah, if that implementation file doesn't #include its header (which you could do; it presumably wouldn't have any effect in normal builds because of the include guards there), clang is not going to be happy. VS may be trying to parse the template without any semantic information, which is not something that clang is really good at, for no particular reason.

It's usually best to just admit that the implementation has to go in the header.

eth0.n
Jun 1, 2012

rjmccall posted:

It's usually best to just admit that the implementation has to go in the header.

Personally, I think the "implementation separate from interface" principle for source code organization is overrated among C++ coders. Even if you split classes between hpp and cpp files, your hpp file still has a bunch of implementation details (like private methods/fields). Consider, if the split source code was really that valuable, Java and C# probably would have kept it.

Separate hpp and cpp files exist purely because of how C++ compilation units and linking work, which it inherited from C. Somehow, it got elevated to a sacred design principle. But true, valuable, separation of interface and implementation is about class design, not where you put your code.

Just put your code in the right file as needed for linking to work right. And don't feel "bad" about putting implementation stuff that needs to be in the header inside the class declaration itself. Don't kill yourself with the ridiculous verbosity of separate template method definitions.

sarehu
Apr 20, 2007

(call/cc call/cc)
Having a separate implementation file makes it easier or at least less diffy to refactor into using explicit template instantiation later.

Harik
Sep 9, 2001

From the hard streets of Moscow
First dog to touch the stars


Plaster Town Cop
Someone doublecheck me on this one:

C++ code:
#include <vector>
#include <cstdio>

int main() {
	std::vector<std::vector<int>> test;

	test.push_back(std::vector<int>());
	auto & ref = test.back();
	ref.emplace_back(1);
	ref.emplace_back(2);
	ref.emplace_back(3);
	test.push_back(std::vector<int>());
	ref = test.back(); /* Use after free here? */
	ref.emplace_back(4);
	ref.emplace_back(5);
	ref.emplace_back(6);

	for (auto & v1 : test)
		for (auto & v2 : v1)
			printf("%d\n", v2);

	return 0;
}
If I understand right, I'm blowing things up because I'm reusing a reference variable which ends up blowing away the vector in test[0]? I don't understand why that's a use-after-free, though, it should end up being the same as test[0] = test[1] - destroying the contents, but not the vector itself.

The code itself was a brainfart that I fixed already, I meant to use a pointer and used a reference instead.

GeneralZod
May 28, 2003

Kneel before Zod!
Grimey Drawer

Harik posted:

Someone doublecheck me on this one:

<snip>

If I understand right, I'm blowing things up because I'm reusing a reference variable which ends up blowing away the vector in test[0]? I don't understand why that's a use-after-free, though, it should end up being the same as test[0] = test[1] - destroying the contents, but not the vector itself.

The code itself was a brainfart that I fixed already, I meant to use a pointer and used a reference instead.

As a hint: adding

code:
test.reserve(2);
after the declaration of test fixes things :)

Xarn
Jun 26, 2015

Harik posted:

Someone doublecheck me on this one:

C++ code:
#include <vector>
#include <cstdio>

int main() {
	std::vector<std::vector<int>> test;

	test.push_back(std::vector<int>());
	auto & ref = test.back();
	ref.emplace_back(1);
	ref.emplace_back(2);
	ref.emplace_back(3);
	test.push_back(std::vector<int>());
	ref = test.back(); /* Use after free here? */
	ref.emplace_back(4);
	ref.emplace_back(5);
	ref.emplace_back(6);

	for (auto & v1 : test)
		for (auto & v2 : v1)
			printf("%d\n", v2);

	return 0;
}
If I understand right, I'm blowing things up because I'm reusing a reference variable which ends up blowing away the vector in test[0]? I don't understand why that's a use-after-free, though, it should end up being the same as test[0] = test[1] - destroying the contents, but not the vector itself.

The code itself was a brainfart that I fixed already, I meant to use a pointer and used a reference instead.

When adding elements to a vector, it will have to reallocate the underlying storage sooner or later. What will happen with the memory it used to use at that point?

Bonfire Lit
Jul 9, 2008

If you're one of the sinners who caused this please unfriend me now.

e: nm.

Sex Bumbo
Aug 14, 2004

Klades posted:

So, here's a question. When you're writing a template class, where do you stick the implementation? I've mostly seen the implementation getting #includeed at the bottom of the header, which works, but the clang-based plugins I use in VIM really dislike it. It means I don't get any meaningful analysis on the implementation code until I compile, and my usually pleasing syntax coloring turns into a big yellow barf.
I'm tempted to just dump all the code into the header but that's messy. Is there a trick to getting this to play nice with the clang static analyzer that I'm not aware of? I know VS+ReSharper has no issues with it, so it can't be some inherent problem that can't be dealt with.

I'm literally hitler so I put most things inline with the class and collapse them in the editor unless the extra indentation irritates me too much.

nielsm
Jun 1, 2009



Harik posted:

Someone doublecheck me on this one:

C++ code:
#include <vector>
#include <cstdio>

int main() {
	std::vector<std::vector<int>> test;

	test.push_back(std::vector<int>());
	auto & ref = test.back();
	ref.emplace_back(1);
	ref.emplace_back(2);
	ref.emplace_back(3);
	test.push_back(std::vector<int>());
	ref = test.back(); /* Use after free here? */
	ref.emplace_back(4);
	ref.emplace_back(5);
	ref.emplace_back(6);

	for (auto & v1 : test)
		for (auto & v2 : v1)
			printf("%d\n", v2);

	return 0;
}
If I understand right, I'm blowing things up because I'm reusing a reference variable which ends up blowing away the vector in test[0]? I don't understand why that's a use-after-free, though, it should end up being the same as test[0] = test[1] - destroying the contents, but not the vector itself.

The code itself was a brainfart that I fixed already, I meant to use a pointer and used a reference instead.

You can't change what a reference refers to, only modify the referenced data.
On your ref = test.back(); line, you aren't making "ref" refer to the newly pushed-in vector, you are (attempting to) call operator= on the first vector pushed in. That then fails because the outer vector has reallocated its storage since then so the hidden pointer in the reference is now invalid.

Solution 1: Use a normal pointer when you will need to point to something different later on, instead of a reference.
Solution 2: Don't dereference pointers/references to objects inside dynamic containers after changing the length of the container, that can invalidate any pointers/references/iterators.

Harik
Sep 9, 2001

From the hard streets of Moscow
First dog to touch the stars


Plaster Town Cop

nielsm posted:

You can't change what a reference refers to, only modify the referenced data.
On your ref = test.back(); line, you aren't making "ref" refer to the newly pushed-in vector, you are (attempting to) call operator= on the first vector pushed in. That then fails because the outer vector has reallocated its storage since then so the hidden pointer in the reference is now invalid.

Solution 1: Use a normal pointer when you will need to point to something different later on, instead of a reference.
Solution 2: Don't dereference pointers/references to objects inside dynamic containers after changing the length of the container, that can invalidate any pointers/references/iterators.

That's what I said in my question, that I was assigning to test[0], not changing ref to be test[1]. I should have included "because you can't rebind a reference" so what I was actually asking was clearer.

Thanks everyone for reminding me about reallocate. Of course that would cause a crash and not just changing the wrong vector.

Xarn
Jun 26, 2015

Harik posted:


Thanks everyone for reminding me about reallocate. Of course that would cause a crash and not just changing the wrong vector.
If you are lucky that is, this isn't Java and we don't have safe memory accesses :v:

Colonel J
Jan 3, 2008
It's a super long shot, but has anyone ever compiled the library "lensfun" on windows (vs2015)? The build instructions make it seem like a super easy task (just run cmake!) but actually trying it out means entering a rabbit hole of unix dependencies; you need glib, which only builds with these convoluted makefiles... I'll admit I haven't tried nmake (just thought of it while writing this) but I doubt it'd be of much help. I found some blog which got it to work with cygwin but of course I try to reproduce his steps and it doesn't work.

I feel like this shouldn't be so drat hard. I wonder how much good code is forever lost to incompatibility between platforms like this. It's quite frustrating, and this isn't the first time it happens to me (although less and less, hopefully, as my skill level goes up). Is it common to just have to give up on compiling certain libraries?

Colonel J fucked around with this message at 04:17 on Aug 18, 2016

fritz
Jul 26, 2003

Colonel J posted:

It's a super long shot, but has anyone ever compiled the library "lensfun" on windows ...you need glib ...

Good freaking luck.

fritz
Jul 26, 2003

That lensfun code is really gross, but I bet you could remove the glib stuff and replace it with modern c++, and it would be not much more than tedious.

EDIT: Also is there anything lensfun does that you can't do with opencv's lens calibration / correction stuff?

fritz fucked around with this message at 04:42 on Aug 18, 2016

Colonel J
Jan 3, 2008
I never checked if OpenCV did that stuff actually. Lensfun has this super expansive database of camera parameters, I don't know if opencv has that, I'll look into it. Thanks for the suggestion. I could just grab the db and find a way to make opencv use it.

I actually thought of rewriting the glib parts from the lensfun code, but wasn't sure how tractable that idea was. I'd sure be proud of myself if I could pull it off.

Bonfire Lit
Jul 9, 2008

If you're one of the sinners who caused this please unfriend me now.

Colonel J posted:

It's a super long shot, but has anyone ever compiled the library "lensfun" on windows (vs2015)? The build instructions make it seem like a super easy task (just run cmake!) but actually trying it out means entering a rabbit hole of unix dependencies; you need glib
You're hosed. Everything that comes out of the GNOME project barely works on Windows, if it does at all.

However, if you absolutely have to go that route: glib needs libffi, zlib and gettext. Of these only zlib is straightforward to compile on MSVC (just run cmake!). libffi's current release doesn't build on MSVC even if you use their lovely mingw-based wrapper; you have to use 3.1 (if you don't want to require MinGW too, here's a CMakeLists.txt and matching fficonfig.h.cmake to help you build it). gettext's code is more fit for the coding horrors thread, and if you want to make it build on MSVC I hope you brought a lot of time and booze; some way too patient people at the WinKDE project have fixed up a (rather old) version to make it work. You'll need to patch it a bit more, and you'll also need win-iconv (which comes with a working CMake build, yay).

e: Oh and before I forget, if you use anything glib on MSVC, you'll have to call _set_printf_count_output(1); from your code before using it (maybe even before initializing it in which case you'll have to patch the glib_init function). You may also have to fix their project files to link against the correct names of the libraries, since in your case it most likely won't be "zlib1d.lib" but "zlib.lib". Some of the other library names will probably have to be changed as well. glib-version-paths.props will need changes as well, but those should be relatively obvious.

Bonfire Lit fucked around with this message at 10:41 on Aug 18, 2016

Doc Block
Apr 15, 2003
Fun Shoe
Using glib even on *nix should be grounds for being fired (or kicked off the open source project).

Does it still call abort() when it encounters an error?

Colonel J
Jan 3, 2008

Doc Block posted:

Using glib even on *nix should be grounds for being fired (or kicked off the open source project).

Does it still call abort() when it encounters an error?

Of course it does!


I'd also like to put in a shameless plug for a question I have regarding Visual Studio Code. I have a project that's getting big and so far have just been using Sublime Text and a makefile on the terminal to build it (on OSX).

I want an IDE because I'm sick of that poo poo; XCode looks so drat complicated and I thought VS Code would hit a sweet spot of simplicty/usability. It's super nice and pretty to use, but I don't know if I can actually make it do what I want.

edit: I bit the bullet and made an Xcode project. It wasn't really that bad in the end.

Colonel J fucked around with this message at 04:31 on Aug 19, 2016

Series DD Funding
Nov 25, 2014

by exmarx
What do you want to do? I'd be shocked if you couldn't make ST run your Makefile and display the results.

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.
I know in vim you can just do :make and it builds stuff and opens the quick fix. I'd expect ST to provide hooks as well, but I've never used it.

Colonel J
Jan 3, 2008
Hmm I shouldve tried it out with Sublime. I just faced my fears and made an Xcode project. I had no luck before but this time it went pretty smoothly. I want breakpoints!

Colonel J fucked around with this message at 04:34 on Aug 19, 2016

Doc Block
Apr 15, 2003
Fun Shoe
Click on a line number to set a breakpoint on that line in Xcode. Clicking on the little breakpoint arrow that appears over the line number will leave the breakpoint there but disable it (click on it again to re-enable); right click on it to bring up a contextual menu that will let you completely remove that breakpoint.

Doc Block fucked around with this message at 05:36 on Aug 19, 2016

Chuu
Sep 11, 2004

Grimey Drawer
edit: realized why that was a terrible idea. sorry.

John F Bennett
Jan 30, 2013

I always wear my wedding ring. It's my trademark.

What language would you recommend to study purely as a hobby, C or C++?

Some background first... I’ve been programming in Java for a few years now and am fairly proficient in it. I have created your typical enterprise applications (including frontend, database, server,...) and now I’m mostly having fun making games for Android.
I have also dabbled a bit in Python.

Now, I’m not looking for employment or even creating fully developed programs. I just want to study in my free time to become better in understanding how it all works on a lower level and I’m not sure if I should choose C or C++ for this.

Beef
Jul 26, 2004

quote:

I just want to study in my free time to become better in understanding how it all works on a lower level

Start with C99/C11, definitely. You can get to the same insights with C++, but you will want to kill yourself before you get there on a hobby basis. Especially coming from a java background, you will see a lot of things that look the same, but mean something really different.
After you feel you really get C, but the lack of advanced abstraction mechanism is a barrier to for your larger code projects, then it is time to switch to C++.


comedy option: TIS-100 :sun:

feedmegin
Jul 30, 2008

For what it's worth, if you do end up learning C++ you can make games/apps for Android in that, too, using Qt :sun:

Dr Monkeysee
Oct 11, 2002

just a fox like a hundred thousand others
Nap Ghost

Beef posted:

Start with C99/C11, definitely. You can get to the same insights with C++, but you will want to kill yourself before you get there on a hobby basis. Especially coming from a java background, you will see a lot of things that look the same, but mean something really different.
After you feel you really get C, but the lack of advanced abstraction mechanism is a barrier to for your larger code projects, then it is time to switch to C++.

This is exactly what I did. I haven't touched C or C++ in about 15 years and wanted to do something in a low-level language for the fun of it. I wrote a unit-testing framework in C11 but when I switched to a hobby project with larger scope I got tired of the lack of abstraction mechanisms and jumped up to C++.

Adbot
ADBOT LOVES YOU

sarehu
Apr 20, 2007

(call/cc call/cc)

John F Bennett posted:

I just want to study in my free time to become better in understanding how it all works on a lower level and I’m not sure if I should choose C or C++ for this.

C is fine or good if you want to understand "how it works." You'll run out of C to learn pretty quickly, and at some point there's more benefit to C++, and it's more for software design education.

I mean basically memory is a big array of bytes, there's structure size and alignment. Look at the assembly output of some simple C functions to understand how function calls work, and... you're done. There isn't really that much stuff at the bottom.

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