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
seiken
Feb 7, 2005

hah ha ha
I'm not a programming beginner, but I've never learned the first thing about parallel programming/threads/coding for multi-core systems/all that stuff, in any language. Given that I use C++ more than any other language, where would be a good place to start?

Adbot
ADBOT LOVES YOU

seiken
Feb 7, 2005

hah ha ha

Kimani posted:

The Little Book of Semaphores is very, very good at presenting the problems associated with parallel programming and the tools used to tackle them. It's language agnostic and should show you all the theory.

I've done threaded stuff on Windows and I've used the critical section ( essentially a mutex ) and semaphore in the Platform SDK. Boost also has a pretty sweet barrier. The terms will make sense once you check out that book.

That's all I got for ya.

Sweet, after reading a couple chapters of that book I understood enough to use the Platform SDK implementations to get my video rendering thingy to do different frames at the same time on different CPUs. (An incredibly simple problem to solve, as it turns out, but it was what I had my sights set on originally.) Thanks, guy!

seiken
Feb 7, 2005

hah ha ha

Chuu posted:

Thanks for the replies. I guess besides the comp-sci 101 examples (tail recursion, loop unrolling, inlining, copy prevention) I don't have a good sense of what's easily optimized and what isn't. Is there some good reference out there that explains modern compiler optimizing techniques?

Don't know if you're looking for something on the web but I believe this is pretty much the general compiler bible: http://www.amazon.com/Compilers-Principles-Techniques-Tools-2nd/dp/0321486811 (second half of the book is mostly optimization)

seiken
Feb 7, 2005

hah ha ha
The derived class needs to construct the base class, and the base class does not have a no-argument constructor. The compiler has no way of knowing that you intend both of the string tname parameters to be the same thing. You need to replace that line with something like
code:
lexicalnode (string tname) : node(tname) {}
explicity calling the base-class constructor.

seiken
Feb 7, 2005

hah ha ha
The error is on line 24? Looks like those quotes around the "r" are not in fact quotes but some fancy two-sided quote special characters (probably from copy-pasting from a LaTeX document or something like that, I imagine). Use regular quotes.

seiken
Feb 7, 2005

hah ha ha
Uh, post the code that determines the value of add_to_group. If subsequent groups don't somehow depend on what items were put in earlier groups, you can easily do the whole thing in one pass with no recursion...

seiken
Feb 7, 2005

hah ha ha
Arguably your code is very clear and nicely-commented I guess but cout << int(0.5 + inputNumber) << endl; does it in one line and is idiomatic enough that I don't see any reason not to use it.

seiken fucked around with this message at 01:22 on Apr 27, 2012

seiken
Feb 7, 2005

hah ha ha
Is there a reason a CGI program written in C++ (even very basic "hello world") would work perfectly on the server when compiled with optimizations off, but give a 500 Internal Server Error with -O1 or anything more? It runs fine on my local machine with either option. I'm compiling on the same architecture as the server (x86-64 linux). Does g++ do optimizations that are only valid for my [distribution/processor/kernel/something else] or something? Am I naive to expect it to work without compiling it directly on the server? (getting shell access is possible but a bit of a hassle. It's probably not actually a big deal to just leave optimizations off but now I'm curious)

seiken fucked around with this message at 15:19 on Jun 16, 2012

seiken
Feb 7, 2005

hah ha ha

schnarf posted:

Issues that only appear when optimization is on usually mean a bug in your code that didn't manifest itself without optimizations. For example, in this fragment of code:
code:
void f(int* p) {
    *p= 5;
    g();
}
If the optimizer inlines a call to f(), and can prove that f() is getting called with a null pointer, it's entitled to never call g(), because it knows that first it dereferences a null pointer, which is undefined behavior. If you're interested in this, check out this series of articles: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

It shouldn't be doing optimizations that are only valid on your local machine, so I doubt it's that -- you should totally be able to compile on your machine.

Yeah, I'm aware of that. But I don't think that's the issue because I can literally compile this code
code:
#include <iostream>

int main()
{
    std::cout << "Content-type: text/plain" << std::endl << std::endl << "hello world" << std::endl;
    return 0;
}
And get
Output on my machine without optimization: hello world
Output on my machine with optimization: hello world
Output on server without optimization: hello world
Output on server with optimization: 500 internal server error

seiken
Feb 7, 2005

hah ha ha
Thanks for the suggestions, guys.

Vanadium posted:

Have you tried it running manually instead of through CGI?
Unfortunately I don't have shell access to the server and I don't think I can do this without that (unless I'm dumb and there's a way).

roomforthetuna posted:

And have you tried static linkage? It's not a great solution but it's often a good diagnostic step.
Aha, linking everything statically does indeed make it run properly on the server with any optimization settings. The program doesn't use anything except the standard libraries so I guess the server has different versions of libgcc / libc++? I probably can't change those so I guess I'll just leave it statically-linked. The program does some CPU-intensive stuff so the optimization is probably more important than the extra 1mb or so size (unless I'm dumb and this is a Bad Idea). Thanks.

seiken fucked around with this message at 22:19 on Jun 16, 2012

seiken
Feb 7, 2005

hah ha ha
Nothing relevant (just logged the fact that it couldn't find a customised 500 error page because I haven't made one).

seiken
Feb 7, 2005

hah ha ha
Ok, another question.
I need reproducible real-number math across compilers and operating systems. I tried for a while to get the built-in floating-point calculations to always give the same result on windows/MSVC and linux/g++ but that seems to be a Pandora's box of black magic tricks and even if I could get it to work I don't really want to rely on such an unstable setup.

Can anyone recommend me a library for this? It's for a game so I don't care much about accuracy. I don't care if it's fixed-point or floating-point. If it has a C++ "drop-in float-replacement class" that's a bonus but I can always make one myself if it's a C library or whatever. The only things I need are for it to be reasonably fast, support a few functions (sin, cos, atan, sqrt, conversion to & from float/int) and the aforementioned determinism.

I really don't want to have to write this stuff myself, but so far I haven't been able to find anything suitable. The fixed-point libraries I can find all seem to lack basic math functions. The only thing that did seem promising was MPFR (and the C++ wrapper), which is good and totally works, except it's variable-precision: I think it's really designed for accuracy and working with thousands-of-bits floating-point representations; when I just want a standard 4-byte float, as far as I can tell, the overhead of variable-precision means MPFR operations are several hundred times slower than the built-in float operations... I don't need blinding speed but that's not good enough! (maybe I'm doing something wrong...? I mean, it seems really slow, even if all the functions are having to do a bunch of unnecessary work just in case the inputs are 1000 bit floats instead of 32)

Any advice? Thanks!

seiken fucked around with this message at 22:24 on Jun 21, 2012

seiken
Feb 7, 2005

hah ha ha

Jabor posted:

A lot of the variability in floating-point results happens because of differences in hardware. So chances are any truly portable implementation is entirely a software implementation, which means some pretty poor performance.

On the other hand, if you can constrain what hardware you're using (for instance, if you can assume x86 w/ SSE), you might have an easier time of it (since now it's just about getting it configured the same way and stopping the compiler breaking it with optimizations).

If you try searching for "reproducible floating-point" you might find something helpful.

Yeah, I mean I can probably assume x86 processor. But I tried for like a week without success to get reproducible results on just MSVC/windows and g++/linux even on the same identical machine! I got very close but eventually the behaviour always diverges. It's very unstable and the web is full of conflicting information about what compiler settings will work, whether it's even possible, and so on. I just want to use something implemented with integer types and know that it's gonna work.

On speed: my game is really very very simple. Software implementation should definitely be fast enough! The problem with the MPFR library is when I replaced all the floats with 32-bit mpfr types, I went from being able to calculate and render tens of thousands of frames per second to less than 10 fps... Even if I only use mpfr types for the engine code, and not rendering (which doesn't need to be reproducible) it slows down noticeably in some of the more CPU-heavy bits. I believe this is because MPFR has a lot of overhead to allow for operations on types of arbitrary precision (including all the data being allocated on the heap internally...). And it's a C library so no templates and nothing gets optimised away, even though I only ever use very low-precision. I'm sure something with a fixed-precision number type (especially fixed-point) would be more than fast enough. I just can't find any good implementations which is very surprising to me.

seiken fucked around with this message at 00:00 on Jun 22, 2012

seiken
Feb 7, 2005

hah ha ha
Thanks for all the replies. I think I didn't make it clear enough that I've already screwed around a lot with FPU floating-point determinism and am just looking for something in software. It just doesn't seem sensible to me to rely on something so unguaranteed that could break for any number of reasons. In the end I think I'm just gonna implement my own fixed-point math because it's really simple and more than accurate enough.

seiken fucked around with this message at 12:46 on Jun 22, 2012

seiken
Feb 7, 2005

hah ha ha

GrumpyDoctor posted:

You could try CORE (which I believe actually typedefs double if you let it) or LEDA which is notable for being apparently the only library of its type that isn't ultimately built on top of GMP.

Hi, really appreciate your input (and those links are interesting even if I don't use them) but I managed to implement fixed-point from scratch already. It works great and seems to be almost as fast as using floats even with my very naive first-attempt implementations of the transcendental functions.

seiken fucked around with this message at 18:17 on Jun 23, 2012

seiken
Feb 7, 2005

hah ha ha
Makes sense. Definitely most of the things I came across that weren't someone else's 15-minute fixedpoint implementation were aimed squarely at science/academic stuff (including those two you linked). I have sin(pi/2)=1.004 and I'm perfectly happy with that! On the other hand I believe fast inaccurate but reproducible real-number math should be a fairly common use-case for games... RTS networking, game replays, etc can be done easily just by recording user inputs with that. Anyway no worries, I shouldn't have been so hesistant to do it myself because it was fairly easy and now I know way more about bits.

seiken fucked around with this message at 16:11 on Jun 24, 2012

seiken
Feb 7, 2005

hah ha ha
Easiest way is to write your code using whatever text editor you like (default is probably half-decent), save it, open a terminal, and type something like
gcc path/to/example.c
It's as easy as that! Then to run it type ./a.out which is what it'll name the output executable by default.

seiken
Feb 7, 2005

hah ha ha

hieronymus posted:

Google is your friend.

The quickest way of doing this is to do Miller-Rabin and Pollard's rho algorithm.

Use Miller-Rabin to figure out whether or not the number is composite - Pollard's rho algorithm does not work if the number is prime, so you need to run a prime detection algorithm before you factor a 64-bit integer.

After that, use trial division for like the first 1000 primes, then clean up with the Rho detection algorithm.


I get the feeling this is for an assignment for a fairly beginner programming class or something of that sort so while your advice is certainly mathematically sound, it's probably overkill and/or not necessarily helpful in this case. The object probably really is just to demonstrate understanding of loops and such, only do these real-world algorithms if you wanna be a superstar!

seiken fucked around with this message at 17:37 on Sep 10, 2012

seiken
Feb 7, 2005

hah ha ha
Ok so I'm sure I must have encountered this issue before but I'm not sure if there's a usual way to deal with it:

code:
class Foo { ... };

std::set< Foo* > some_foos;

bool is_there_a_foo( const Foo* foo )
{
    return some_foos.find( foo ) != some_foos.end();
}
const Foo* is clearly a reasonable type for the argument to is_there_a_foo - std::set doesn't know its template argument is a pointer type so it's not even going to dereference foo it let alone modify the pointed-to stuff. But find takes a const (Foo*)& which is not at all the same thing so this won't compile without a const_cast. This seems pretty basic so what's the done thing here?

seiken fucked around with this message at 01:18 on Sep 12, 2012

seiken
Feb 7, 2005

hah ha ha

ZombieApostate posted:

Is there a reason you have to have Foo*'s in the set, or can you have just Foo's? Otherwise I think you can write a replacement comparison function so that it looks at the pointer instead of the address of the pointer like it is trying to do (derp) contents of the pointer instead of the pointer itself. I think the std containers are more designed to store instances than pointers. Or I could be totally miss-remembering this, I'm kind of sleep deprived right now.

Storing pointers in containers is a perfectly reasonable thing to do and a custom comparator has nothing to do with the argument types of the functions I'm afraid. My question is about how to be const-correct in a relatively simple situation without needing a const_cast

seiken
Feb 7, 2005

hah ha ha

rjmccall posted:

You just need a const_cast. All of the internal machinery in std::set wants to pass around values of the key type, not values of types to which the key type is convertible. One reason why is that that's all the comparator is known to support — you may have given your set a comparator that takes const Foo*s, but an arbitrary std::set of Foo*s is allowed to have a comparator that just takes Foo*s.

It comes down to philosophy. What types should you be able to pass to find()? There are two ways to answer that: intrinsic and extrinsic. There's only one type which you should intrinsically be able to pass to find(), and that's the set's actual key type, because the comparator promises to work with that. But extrinsically, you should be able to pass anything which can sensibly work with the comparator you've provided. The extrinsic answer is generally the more flexible and accepting answer, but it requires type-checking and rebuilding basically the set's entire search machinery with an arbitrary new type — i.e., in C++, it requires templating everything to hell and back. That in turn means inferior error messages, build times, generated code size, etc.

Thanks, great answer, just wanted to make sure I wasn't missing something obvious & better (const_cast is what I've been doing so far)

seiken
Feb 7, 2005

hah ha ha
Also, writing floating-point values (as text) to a file and reading them back in won't necessarily give you the exact same values. Unless you care about the file being human-readable, you might want to consider writing binary data instead (this is easier and will improve filesize, performance and accuracy).

seiken
Feb 7, 2005

hah ha ha
There's no difference between structs and classes in C++ except that structs have default visibility public and classes have default visibility private.

By convention structs are used for "plain old data" types and classes for more complicated things but it's just preconceived notions, it's not enforced by the language in any way.

Edit: technically structs/classes also default to public/private inheritance respectively when not specified, though I've never really seen this come up in practice.

seiken fucked around with this message at 16:01 on Feb 19, 2013

seiken
Feb 7, 2005

hah ha ha
You could always just do
C++ code:
breakEarly = new int[necklaces * depth];
and index with
code:
i * depth + j

seiken
Feb 7, 2005

hah ha ha
What would you intend to happen if you passed the wrong kind of derived class Structure to the function, and if the answer is "it wouldn't work", then what's the point of the function being virtual at all? If the answer is "it wouldn't compile" you might want templates rather than inheritance

seiken fucked around with this message at 23:07 on Mar 21, 2013

seiken
Feb 7, 2005

hah ha ha
I kind of think this is an X/Y problem and you should explain what you're actually doing and why you want this because the use case you gave is sort of odd.

seiken
Feb 7, 2005

hah ha ha

just a butt posted:

What I want to do is create a class that takes input data, does calculations and poo poo on it, and returns a pointer to the processed output data. The struct in this case is metadata associated with the input data.

I wanted the polymorphism aspect because there's a lot of possible stuff I could do with the input data, and it all requires different metadata (and different output structs). But as far as the end user is concered all he needs to do is call process(struct *metaData, inputType *inputData).

If rjmccall or turkey story disagree then go with whatever they say but I think you're over-engineering this (or still not giving the full story). From what you've said you just want some functions with arbitrary parameter types and semantics to share the same name, which is handled quite well by overloading:

C++ code:
struct Structure {};
struct OtherStructure {
  int member;
};

struct OutputStructure {};
struct OtherOutputStructure {
  int member;
};

OutputStructure* process(Structure* metaData, InputType* inputData);
OtherOutputStructure* process(OtherStructure* metaData, InputType* inputData);
Turkey Story's post is a great post but since you haven't given any correspondences among the structure types or the various implementations of the process function, I don't see any reason why virtual functions or templates would be useful

seiken fucked around with this message at 01:16 on Mar 23, 2013

seiken
Feb 7, 2005

hah ha ha

quote:

I have been idly working on a problem I've had off and on

What you're describing is essentially a very constrained kind of regular expression engine (with only alternation and concatenation) which should be pretty easy to implement if you look up how.

seiken
Feb 7, 2005

hah ha ha
I apologise for not actually being able to recommend a resource that I have personally used, but with some quick googling I found these online lectures on the theory that look pretty decent and this stuff about actual implementation might be useful although some of them are more focused on the speed stuff which you don't need if you're pre-generating this. And you don't need the star operator or any nesting so you don't need half the code also

A compilation book, while certainly interesting and valuable, may well skip the foundation regex/finite automata stuff that you really want and go straight to lexing, which is probably more than you need for this problem. edit: I know the dragon book definitely has the automata and regex stuff, but you'd only need like the first chapter

Edit again: to clarify, all you need to do to solve your specific problem is precompute a DFA table from e.g. "cat|hat|hood" and use that to process the stream at runtime.

seiken fucked around with this message at 02:22 on Mar 23, 2013

seiken
Feb 7, 2005

hah ha ha
You can, but it doesn't make a lot of sense because you'd be returning a copy anyway. But if you return it as a const reference then yes.

seiken
Feb 7, 2005

hah ha ha
I have a (mathematical) vector class which stores its elements in an array. However it'd be nice if I could also access the elements with their common names (v.x, v.y, etc) when the vector is a small enough size.

My first try at a solution:

C++ code:
template<typename T, std::size_t N>
stuct vec_accessors {
  vec_accessors(T* elements) {}
};

template<typename T>
struct vec_accessors<T, 3> {
  vec_accessors(T* elements)
    : x(*elements)
    , y(*(1 + elements))
    , z(*(2 + elements))
  {}

  const T& x; const T& y; const T& z;
};

// ... and so on ...

template<typename T, std::size_t N>
class vec : vec_accessors<T, N> {
public:

  T elements[N];

  vec()
    : vec_accessors<T, N>(elements)
    , elements{0}
  {
  }

  // ...

};
This basically works; the problem is that if I make the references x, y etc non-const (so that I can mutate the vector through them), then I can even mutate a const vec through them since the const-ness doesn't propagate through references.

It's not the end of the world, I could always add functions and use v.x(), or just use the long names v.elements[0] for mutating, just wondering if there's a better way?

seiken fucked around with this message at 19:09 on Apr 20, 2013

seiken
Feb 7, 2005

hah ha ha

That Turkey Story posted:

Don't do that thing you're doing with the references. That const issue is just one of a slew of problems. You're making the type larger and making accesses harder to optimize, both of which I would imagine you would like you avoid for something as low-level as a vector type. Just make named accessor functions. As for alternatives, a similar question came up a few pages back I think. What I personally do is I have empty types that I use as accessors, so I can do things like my_vector[x] = 5; or my_vector[right] = 5, where "x" and "right" are just instances of those empty types and the vector type has operator[] overloaded accordingly. Simple accessor functions is more concise and I would just recommend that unless you really want or need something else.

Yeah, I knew it was gonna be bad for optimisation, but luckily you've come along with this v[x] idea that I really like. Thank you.

Edit: in case anyone else has this problem, this is what I came up with
C++ code:
template<std::size_t N>
struct element_accessor {};

template<typename T, std::size_t N>
class vec {
public:

  T elements[N];

  template<std::size_t M, typename std::enable_if<(N > M), int>::type = 0>
  T& operator[](const element_accessor<M>& e)
  {
    return elements[M];
  }

  template<std::size_t M, typename std::enable_if<(N > M), int>::type = 0>
  const T& operator[](const element_accessor<M>& e) const
  {
    return elements[M];
  }

  // ...

};

namespace {
  const element_accessor<0> x;
  const element_accessor<1> y;
  const element_accessor<2> z;
  const element_accessor<3> w;
}

seiken fucked around with this message at 14:27 on Apr 21, 2013

seiken
Feb 7, 2005

hah ha ha

That Turkey Story posted:

Something along those lines should be fine. Depending on whether or not you declare an explicit default constructor will affect your ability to do those declarations of x, y, and z in that manner, at least in a standard-compliant compiler (I think VC++ lets you get away with it).

Edit: There are technically potential ODR issues. If you're a pedant, the "correct" way to do the declaration of those x, y, and z names is either with externed variables or with references. It's probably unnecessary, though boost often does little dances for declaring objects like this. Here is how Boost.Units does it, for example (this macro is used for things like "meters" and "seconds" when you make a quantity like 5 * meters / second).

Thanks for the ODR info, I've fixed that. I'm not sure what difference an explicit default constructor would make here, though. For the record I'm using gcc 4.7 with -Wall, which didn't seem to complain about either of the two things you pointed out.

seiken fucked around with this message at 17:31 on Apr 21, 2013

seiken
Feb 7, 2005

hah ha ha

shrughes posted:

Just use `buttIter->->fart()` syntax.

only works on boner arrays

:colbert:

C++ code:
template<typename T>
struct stupid_ptr_base {
  T* t;

  stupid_ptr_base(T* t) : t(t) {}

  T& operator*() const
  {
    return *t;
  }

  T* operator->() const
  {
    return t;
  }
};

template<typename T>
struct stupid_ptr : stupid_ptr_base<T> {
  stupid_ptr(T* t) : stupid_ptr_base<T>(t) {}
};

template<typename T>
struct proxy_base {
  T* t;

  proxy_base(T* t) : t(t) {}

  // Change `&&' to `const' to compile on GCC (allows fuckery).
  T* operator->() &&
  {
    return t;
  }
};

template<typename T>
struct proxy : proxy_base<T> {
  proxy(T* t) : proxy_base<T>(t) {}
};

template<typename U>
struct proxy<stupid_ptr<U>> : proxy_base<stupid_ptr<U>> {
  typedef stupid_ptr<U> T;
  proxy(T* t) : proxy_base<T>(t) {}

  // Change `&&' to `const' to compile on GCC (allows fuckery).
  proxy<U> operator--(int) &&
  {
    return proxy<U>(proxy_base<T>::t->t);
  }
};

template<typename U>
struct stupid_ptr<stupid_ptr<U>> : stupid_ptr_base<stupid_ptr<U>> {
  typedef stupid_ptr<U> T;
  stupid_ptr(T* t) : stupid_ptr_base<T>(t) {}

  proxy<U> operator--(int) const
  {
    return proxy<U>(stupid_ptr_base<T>::t->t);
  }
};

#include <iostream>

struct foo {
  int a;
};

int main()
{
  foo f;
  stupid_ptr<foo> ff(&f);
  stupid_ptr<stupid_ptr<foo>> fff(&ff);
  stupid_ptr<stupid_ptr<stupid_ptr<foo>>> ffff(&fff);

  f.a = 1;
  std::cout << f.a << std::endl;
  ff->a = 2;
  std::cout << f.a << std::endl;
  fff--->a = 3;
  std::cout << f.a << std::endl;
  ffff----->a = 4;
  std::cout << f.a << std::endl;
}

seiken
Feb 7, 2005

hah ha ha
Don't take me as a language expert, but I would guess it's because, while arrays decay to pointers to their first element, the reverse is not true. "a" has the type char* which you can't assign or initialise an array with in general. The fact that you can initialise arrays this way normally at all (like char array[] = "foo") is, I believe, a special-case exception in the language, that won't work in other settings. (If you change the char name[8] to a std::string it will work.)

Edit: I guess I gave the fact it didn't work too much credit.

Edit: for what it's worth, it doesn't work on the latest GCC either.

seiken fucked around with this message at 21:26 on May 28, 2013

seiken
Feb 7, 2005

hah ha ha
I'm not familiar with how the new brace-initialisation syntax actually works, but I'm pretty sure as soon as you pass a char* into a function then you can't initialise an array with it. vector is obviously using a function to initialise here, so I don't see why this could work. Is there some magic about initializer_list that preserves the string-literal-ness of the literal?

Edit: oh, the structs get constructed before they get passed into the vector constructor, I guess? That makes sense.

seiken fucked around with this message at 21:44 on May 28, 2013

seiken
Feb 7, 2005

hah ha ha

Sintax posted:

I got back to coding lately and was looking for a way to write 'global classes' without resorting to something like a singleton. I ended up abusing the static keyword to make classes that look like this (some kind of mouse wrapper):

code:
class Mouse
{
public:
	static void SetMousePos(Vector2f newPos);
	static Vector2f GetPos();
private:
	static Vector2f pos;
};

#include "Mouse.h"

void Mouse::SetMousePos(Vector2f newPos)
	{ _pos=newPos; }

Vector2f Mouse::GetPos()
	{ return _pos; }

sf::Vector2f Mouse::_pos;
This is the simplest example I could find, which let's me do something like easily get the Mouse's position from just about anywhere with Mouse::GetPos(). The ugliest part is defining the private variables at the end of the .cpp, but it overall makes me feel a lot better than using the singleton syntax.

It works but since this is C++ I know there's a problem with the approach. Is my use of global functionality abusive? Is this creating a bunch of copies of _pos? Is there a better way to access single-instance classes?

I mean it's not necessarily wrong but you're really just recreating namespace functionality in a different way. The mouse position in this particular example is essentially a global variable and you should regard it as such. (For something like a mouse position that is likely totally fine, just don't make the mistake thinking putting things in static accessor functions magically makes them not global variables)

seiken fucked around with this message at 12:59 on Jul 20, 2013

seiken
Feb 7, 2005

hah ha ha
Don't reuse the variable name i because your debugger is broken? I think you wanted the coding horrors thread.

Aside, I kind of think number of branches or loops is a much better heuristic for "is this function too big" than number of lines.

seiken fucked around with this message at 01:45 on Jul 21, 2013

seiken
Feb 7, 2005

hah ha ha

Suspicious Dish posted:

That sounds like a practical approach to me. The tools are lovely, but everything else is shittier, so let's make our lives easier by working around the tool.

Sorry, I didn't necessarily mean you shouldn't rename the variable to avoid the problem. Just that the fact that doing so seems like a reasonable solution is appropriate for the coding horrors thread.

vvv because the debugger should loving work that's why, it's crazy you have to do weird workarounds

seiken fucked around with this message at 23:17 on Jul 21, 2013

Adbot
ADBOT LOVES YOU

seiken
Feb 7, 2005

hah ha ha

Rocko Bonaparte posted:

2. Sane error messages when I gently caress up templates, if that is at all possible. I heard clang is better about it than a lot of things.
3. Some autocompletion--as much as can be possible with C++, with some good ability to find usages and declarations of things.
4. Reasonable ability to compile back to Windows (deliberately vague).

I was going to default to trying NetBeans with Clang.

2. Clang is indeed the best. Super-latest versions of GCC are catching up a little in some respects (still not great about templates)
3. YouCompleteMe is hands down the best but you have to use Vim
4. Keep to the stuff here, I guess.

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