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
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
Google test is decent and usable. There's a bunch of interesting-looking C++11/14 libs on github that I haven't yet tinkered with as well, which promise to be much less macro-heavy and perhaps more actively maintained.

Adbot
ADBOT LOVES YOU

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
Qt is kind of worryingly heavyweight but it works pretty well and is easy enough to use in general. No idea what specific quirks there might be on windows, let alone when trying to use VS.

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

Xarn posted:

What is a nice and sane C++ concurrency library? This means higher level than <thread>, <mutex> et al. and less macroy than OpenMP pragmas.

Bonus points if it runs on Windows as well as on Linux.
What exactly do you want it to do for you?

Joda posted:

Why would I be getting an internal compiler error on a piece of code I've compiled with the exact same compiler hundreds of times before? I'm using g++ 4.9.something on MinGW64. On my current project I'm suddenly getting errors on an include of <vector> that seems to refer me to their implementation of initialiser lists.

It's telling me to file a bug report to the mingw team, but I'm not sure how it can suddenly become bugged from one day to the next. My code base is literally the same as I succesfully compiled on the same system just two days ago.
Maybe something clobbered your environment variables?

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
Build system chat:

I ultimately just gave up and hand-rolled a python script to produce ninja files. Maybe Bazel will become good someday.

Tup's pretty neat in a gimmicky kind of way, but it relies heavily on magic and is basically just one guy and he makes some weird design decisions.

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
It doesn't play well with dependencies from the host system (because you can't sanely call pkg-config or similar) and as far as I can tell it's not realistic to vendor all your dependencies the way Google does with Blaze (because they'll have non-Bazel build systems and you really don't want to maintain your own build system of third party code). This leaves you with a build system that's only useful for projects without significant dependencies, and for projects without significant dependencies you can probably get away with a simple shell script anyway.

It's also really awkward to use anything but the exact toolchain configuration that some engineer at Google assumed everybody would always want, because it relies on these great big sparsely-documented toolchain definition files. For example, I like to use clang 3.7 with libc++ on linux, but by default Bazel will have none of that. In general, doing anything off the beaten path (say, calling out to custom tools) rapidly lands you in territory with little if any documentation. Note also that the beaten path is almost entirely Java-related.

My understanding is that they're working on fixing the first issue, at least, so maybe someday it'll be the cmake killer we all want, but it's not there yet and Google might just decide to abandon the effort before it gets close.

Even ignoring all those issues, though, it's still a huge enterprisey java project with bad startup times and tons of its own dependencies and so forth. Not really what I want in a fundamental build tool.

Ralith fucked around with this message at 09:13 on Nov 10, 2015

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
It's worth noting that completely controlling the build environment is generally a great idea, especially for larger projects. It's just that right now, say, Nix (or even just a pile of shell scripts) does a better job of that than Bazel for anyone who isn't Google.

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
What CPUs are you testing on?

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

JawKnee posted:

my local machine is:

Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz

I'm also testing on some servers my school provides which have:

AMD Opteron(tm) Processor 6172
Neither of those CPUs implement the instructions you're trying to use.

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

Plorkyeran posted:

For purely internal software, absolutely. For anything intended to be built and run by third parties on their machines it's not really an option.
To the contrary, it typically makes distribution to third parties far less painful (up to compatibility of glibc/kernel/etc), especially if you target windows. Making it convenient for third parties to build is another matter, and is of course what good tooling is supposed to address. For example, Nix makes it really easy.

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
Instead of returning a bool and taking a reference argument, return a std::optional<int> or whatever.

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

OneEightHundred posted:

If you like C# idioms then you're going to want to strangle someone when you find out what happens when you try to read a value from an STL map by indexing it with a non-existent key.
You want the 'at' method.

Good rule of thumb for standard C++ and major libraries in general: If something seems obviously missing, it's probably there under another name, and you should go check the documentation to find out what that name is.

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

sarehu posted:

Don't use non-const references. (Except where you're supposed to.)
There's nothing wrong with mutable references in appropriate, unambiguous places.

sarehu posted:

Edit: Also, even for reasonable complex types, the default initialization is usually quite fine. Especially if you're willing to copy or move it by returning a std::optional.
Default initialization can be very expensive while moving remains cheap, and (N)RVO should generally preclude any copy or move whatsoever regardless.

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

sarehu posted:

Not for general purpose use.
Clearly defined output parameters are perfectly legitimate, although output parameters in general are best avoided if possible of course.

sarehu posted:

How? I can imagine it being true for a contrived type, like a not-null shared pointer, but realistically, how?

Edit: Also, the point is that if you're willing to copy or move it, it probably is fine to default construct anyway. It doesn't matter whether that particular piece of code is actually copying or moving.
Anything at all that allocates significant memory, for example? RAII in general makes abuse of default value as "no value" awkward at best. As such, being willing to move something does not mean you're willing to default construct it. You also shouldn't treat "copy or move" as if they're interchangable. And again, (N)RVO means that returning an object will not typically involve either.

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
Another way to make it clear that a variable is an output is good name choice. Of course, this all becomes a non-issue if you just output data by returning it instead.

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
I would instead return tuple<optional<T>, std::string::iterator> or something analogous. Avoids copying/moving your entire remaining input (which might be arbitrarily large) as a bonus.

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
Try compiling with AddressSanitizer or running inside valgrind.

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
I don't find defining throwaway structs and accessing their members to be at all onerous :shrug:

Given that typing is certainly not the hard part of programming, a few extra characters compared to some ideal pattern-matching world is not a very high price to pay for unambiguous readability.

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

Phayray posted:

Derp, of course you guys are right, I was deleting them somewhere else but not clearing the vector. Saw it as soon as I looked at it this morning, I guess I just needed some sleep!
AddressSanitizer would have made this immediately obvious. Try it next time!

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
Also try AddressSanitizer.

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
Valgrind and asan are both handy for those because they tend to help isolate the cause of the bug rather than the symptoms.

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

Hughlander posted:

This is really well times part of the thread. Asan is exploding on a bad read from a dlopen in an android app. So some static being initialized somewhere in the 30 meg library is misbehaving. What are our options to track it down? I'm thinking of we could dump the .init of the elf we could get the order of init and add some logging to bisect it. But not sure if that's possible or if there's a better way.
By "asan is exploding" do you mean it's detecting an error or is itself malfunctioning? If the former, it should usually give you a detailed backtrace (which, if you're using old tools or are in a weird environment, may need symbolization).

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

Hughlander posted:

Sorry that was poorly written. It is finding a read overflow but gives no traceback just the PC and some registers. Running the PC through the sym file generated for brake pad doesn't show it as in our code at all.

If we could generate a full traceback for it on Android I'd be ecstatic.
Ah, it's always frustrating when that happens. Is it possible to run your code in rr?

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

JawKnee posted:

I'm getting a memory leak but I'm unsure what's causing it.
It's also worth noting that, illegal malloc shenanigans aside, you'll run into far fewer memory issues in general if you use C++11 smart pointers like std::unique_ptr appropriately, as this will result in intended behavior automatically being produced in the destructor/move constructor/etc without any further boilerplate. In modern C++ you should think very hard before using a raw pointer for anything that has any kind of ownership.

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

JawKnee posted:

I'm wrapping my head around these currently, or attempting to anyhow. Should I only be using smart pointers when something needs to be dynamically allocated?
If something does not otherwise need to be dynamically allocated, then of course don't add gratuitous smart pointers into the mix. They're there to manage ownership, and ownership is generally not an issue for values that are not dynamically allocated (i.e. are on the stack, are a regular member of another object, or are global).

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

The Gay Bean posted:

Assume I have several small bits of work to be done, that I want to parallelize. Each bit of work is small, and will be done at ~30 fps; the work must also be done sequentially (video encoding, if you're curious, but I'm curious about the general case). My current instinct on how to approach this would be one of two ways:

code:
std::thread thread1(&myWorker1,mywork1);
std::thread thread2(&myWorker2,mywork2);
...

thread1.join();
thread2.join();
Or, using OpenMP (which unfortunately doesn't work in the version of Clang that Apple ships with). My questions are:

1. Is there anything braindead about either of the above approaches?
2. Is there a better way?

Assuming this is purely CPU-bound work, you probably want to use a thread pool with a work queue. The thread pool can spin up exactly the number of threads that your hardware can execute most efficiently without any excess overhead.

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

The Gay Bean posted:

Yeah, I've used that approach in other cases, but the problem here (and something I omitted before) is that myWorker1, ... in this example all have an attached object/state for a video encoder. The encoder has to receive frames in order. I'm treating the encoder as a black box in this case - there are a lot of ways to parallelize video encoding but I'm not concerned with that for the sake of this example. (in actuality, each encoder state it spinning up threads internally as far as I can tell).

So another approach is to maintain N threads for N encoders and feed queues for all of these encoders. Given the two cases - N persistent threads for N encoders vs. creating a thread for each loop - is there a large difference in speed?
I'm confused. Are you trying to perform strictly sequential operations on a single object? Then don't use threads at all, especially if it's already taking advantage of hardware concurrency internally. Are you trying to write a tool that can encode a bunch of unrelated video in parallel? I'd just write a tool (or, better yet, use an existing one like ffmpeg) that can encode a single thing at a time, and launch however many of them is necessary to saturate your hardware.

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

The Gay Bean posted:

My question is whether or not there is some theoretical reason why the above would be worse than having 4 persistent threads.
Oh, I see. I would definitely set up 4 persistent threads.

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
Your continue statement is unnecessary. You can have your loop test any condition you like, but the question of "how do I handle user input" has wildly different answers depending on your environment.

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

PRADA SLUT posted:

If I put a cin somewhere, it will pause on the cin to wait for input, and thus, won't loop. Normally that's what I'd do, but I want the script to run indefinitely unless the user actually does something while it's looping.
You'll need to either use a platform-specific multiplexing scheme (e.g. select) or multiple threads.

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

PRADA SLUT posted:

What would be the simplest way to do this under OS X?

Selecting on the standard input file descriptor should work there.

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
If you want to use a for loop like that, the easiest approach would be to define an array of 4 ints, then in each iteration of your outer loop, repeatedly generate numbers until you get one that isn't in the part of the array you already filled in. Be careful not to examine elements of the array that you haven't filled in yet (they'll have undefined values). For something a little more modern and well-behaved than (s)rand, you might also want to look into C++11 random number generation.

e: Also, not sure if you realize this, but standard convention is to do loops such that the counter starts at 0 and the the condition is < N for some N. This makes manipulating arrays more convenient.

Ralith fucked around with this message at 08:22 on Feb 1, 2016

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

PRADA SLUT posted:

I noticed that after. It still outputs correctly.
Even if you clip a wire and live, you're not an EOD tech.

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
Clang tends to give more helpful errors in cases like this, so you might consider trying it next time you're deep in template shenanigans and nothing makes sense.

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

JawKnee posted:

there is no native tool for doing GUIs that is crossplatform though - I just went through trying to do this for an application I was working on.
:confused:
wxWidgets, GTK, Qt, Tk, ...

I've recently learned that packaging GTK programs for non-linux is a huge pain though. wxWidgets is good at looking native on all platforms, so I'd try that first.

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
Doesn't goto also skip destructors that would otherwise be called when control leaves a given block? That could cause all kinds of trouble, especially if you use RAII much.

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
Sometimes refactoring is necessary to allow resource ownership to be explicitly encoded. Do it, preempt the otherwise nearly inevitable leaks, and try to plan ahead better next time.

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

Volguus posted:

I understand that and I agree ... usually ... but in this particular case the struct itself is the owner.
Well, who owns the struct? Is there anything stopping you from exposing a wrapped version of it with a destructor, move constructors, etc?

It's possible for a poorly designed or sufficiently foreign library to force you to write ugly code, but I've worked extensively with that type of struct-with-a-pointer C API in e.g. libuv and never had trouble applying safe(r) resource management with it.

Ralith fucked around with this message at 02:53 on Mar 9, 2016

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

Xarn posted:

What do I need to find out and replicate in a VM, to be able to precompile .o files in a VM that will link properly when used on the real machine?

I already know that it is running Debian Jessie, is using g++ 4.9.2 and should be able to find out anything else I will need to.
Make sure you're building against headers for versions of your dependencies which are ABI-compatible between the two machines. The easiest way to do this is of course by using exactly the same versions of everything.

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

Harik posted:

How do you setup an environment where --sanitize=memory works? I.E., I need a completely parallel set of libraries that only get linked in my test program, since the last thing I want is system-wide libc having memory tooling enabled.
It's a big hammer, but I really like using Nix to set up reproducible build environments independent of the host system (and eachother). You should be able to install it on just about anything other than windows, and then you set up an environment like this

default.nix in your project dir:
pre:
with import <nixpkgs> {};
{ my-dev-env = stdenv.mkDerivation rec {
    name = "my-dev-env";
    version = "0.0";
    buildInputs = [ cmake libuv libpng freetype SDL2 epoxy pkgconfig ];
  };
}
and enter it from that directory with
pre:
$ nix-shell .
Note that mixing nix and host system dependencies doesn't generally work.
(adapted from the wiki)

Modifying the build process of existing packages to get features like msan set will take a bit more work but is fully supported.

Adbot
ADBOT LOVES YOU

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

Harik posted:

I should do that. I've got three targets - amd64, arm-linux and arm-android-linux, and it while the builds are automatic the scripting is custom and somewhat fragile.
I've never actually played with the cross-compilation support, though I understand that it exists. Post your results if you have a go at it!

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