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
Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Hammerite posted:

I am writing some code which will deal with large-ish (a few thousand members) arrays of small integers (like, no more than 4 digits). Should I use short, or just go with int? I know that short is at least 16 bits, so there is no question of it being big enough, I just wonder if it will be looked at as premature optimisation and/or an ignorant ineffectual attempt to optimise (because I don't know whether it, in fact, optimises anything)

Disclosure: I am writing code for a evaluation exercise from a company to which I am applying for a job.

If this is for an embedded system, using the smallest type that can hold all required values makes sense. Otherwise, I'd call it premature optimization.

Adbot
ADBOT LOVES YOU

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Subjunctive posted:

I think he's asking about the storage type rather than the index type; the latter is size_t all the way IMO.

Actually, the index type in C++ is ptrdiff_t (13.6.13). :science:

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

seiken posted:

As Otto said, the fact that you don't care about the relative ordering of only red or only blue means this is an unstable sort. The fact that a simple linear-time algorithm exists is because you have exactly two different keys (red and blue). For three or more keys this won't work and you have to use a general n log n algorithm or radix sort or similar. It's somewhat common in parameterised computer science problems that the problem with K=2 is somehow fundamentally "much easier" than the problem for any greater K (see also SAT, graph colouring). I don't know if there's a name for that particular phenomenon, though.

You can sort in O(n) for three keys - that's Dijkstra's dutch flag problem.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...
Want to have your mind completely blown?

This is legal syntax in C/C++:
code:
int fart(int butt[])
{
    return 2[butt];
}

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

The Laplace Demon posted:

code:
and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq
Whoever invented those, and digraphs, will burn in one of the sultrier corners of Hell.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Suspicious Dish posted:

What if your source file is stored in a character encoding which flat out doesn't have representations for those tokens?
Then you can take your EBCDIC or whatever and go on writing FORTRAN, COBOL and PL/1, in whatever cave you crawled out of. :colbert:

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

qntm posted:

I'm new to C++. I am using a class whose constructor has a reference parameter. I just discovered that inside the constructor, the class actually takes a pointer to this reference parameter and stores that pointer as a member variable.

Just assume that references are pointers that don't require using '&', '*' or '->'. That's how the compiler will treat most of them anyway.

References are a syntactic kludge that is needed to allow overloading assignment operators.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

qntm posted:

This is going to make my life extremely hard though :(

C++ is for men, not boys. :clint:
Insane, masochistic men, but still.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Paul MaudDib posted:

code:
	child_func( ..., validation_data_array + output_offset, ...);

That's undefined behavior if 'validation_data_array' is NULL.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

The Gay Bean posted:

I have a custom data class that is formed for and used by a specific algorithm. The data backing it is just a collection of 1D and 2D STL vectors and a cv::Mat (which can be stored using a 2D STL vector). I coded up serialization using boost::serialization because it's easy to read and fairly standard, but it turned out to be slow as poo poo in debug mode - taking several minutes to write / read a 1 GB archive. This is reduced to like 10 seconds in release mode, but for the time being I need to run the code in debug mode a lot, and I can't put up with those kinds of wait times.

Can you split the implementation to put the serialization code in a separate source file (that can be compiled in release mode)? (Of course assuming that you don't want to debug that code, specifically, and that debug mode doesn't cause changes in data layout or other incompatibilities that would preclude mixing debug- and release-compiled code.)

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Newf posted:

Are the following two lines of code the same thing?
code:
int* a = &b;
int *a = &b;

Essentially yes. Some people recommend using the style of the first line. These people are wrong, because syntactically the '*' binds to the identifier, not the type. The following does not declare two pointers:
code:
int* p, q;

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Vanadium posted:

just use std::add_pointer<int>::type a, b;

The Laplace Demon posted:

Just use template<typename T> using ptr = T*;

See all you fine dandies so proud, so cock-sure, prancin' aboot bein' able to use C++11. I'm still waiting for the day I can finally write auto butt = fart(); :(

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Newf posted:

Here's a more general (more stupid?) question about C(++). Why is it that when I look up something like ArrayList class from Java or .NET I'm brought to comprehensive documentation from the language specifiers (eg, Oracle and Microsoft) but when I look up std::vector I find sites like cplusplus.com?

Is there some hidden thing that I'm supposed to be using as a reference?

C++ is not owned by a single company; the relevant reference would be the ISO C++ standard. It's not available online (though draft versions are) because it actually costs money. The latest drafts are available at the C++ Standards Committee website.

However, I wouldn't recommend using the standard for learning C++ - it's mostly an implementer's reference. Books like The C++ Programming Language are better for that.

Sites like the ones you already found are indeed your best bet for online searchable reference material - since it isn't a single-vendor language, there is no one authoritative C++ reference site.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Hammerite posted:

An earlier version of the method did something like this:

code:
bool tooBig = false;
try
{
    inputInt = std::stoi(input); // not strtoi()!!!
}
catch (std::out_of_range)
{
    tooBig = true;
}
if (inputInt > maxAllowedValue)
{
    tooBig = true;
}
if (tooBig)
{
    cout << "That number is too big!" << endl;
    return;
}
until I looked at it and thought, "screw it, I can test both things in the same place and unify what happens when the number is too big". That's when I moved the test inside the try block and added the throw statement. It meant I could get rid of the boolean flag variable.

I would probably rewrite that to something like
code:
try
{
    inputInt = std::stoi(input);
    if (inputInt <= maxAllowedValue)
    {
        // Valid input
        return;
    }
}
catch (std::out_of_range)
{
    // Error, handled below.
}

cout << "That number is too big!" << endl;
return;

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Xeom posted:

I am trying to understand some of the differences between the different constant types when defining a function in a class. Lets assume all this code is written within a class definition. Please let me know if I have misunderstood anything, I have a feeling I got something wrong.

code:
 classtype &thing1(int a, int b) { do things; return *this; };
Here we have a implied constant to this. That is the functions pointer will always point to the object that it was called with.

code:
 classtype &thing2(int a, int b) const { do things; return *this; };
Here we add a low level constant that makes it so this function cannot edit the object.

code:
const classtype &thing2(int a, int b) const { do things; return *this; };
This constant in front is just for having constant and non constant versions of you function.

The basic thing to understand is the difference between a constant pointer and a pointer to a constant.
code:
int a, b;

int *p = &a;                 // non-constant pointer to non-constant int
p = &b;                      // OK
*p = 42;                     // OK

int *const q = &a;           // constant pointer to non-constant int
q = &b;                      // error, q is constant
*q = 23;                     // still OK

int const *r = &a;           // non-constant pointer to constant int
r = &b;                      // OK
*r = 17;                     // error, *r is constant

int const *const s = &a;     // constant pointer to constant int
s = &b;                      // error, s is constant
*s = 4;                      // error, *s is constant
Now, in a class member function, this is always a constant pointer. The class instance that it points to (i.e., *this) is constant if and only if the function itself is marked const.

Two more traps for the unwary:
code:
int const *p;
const int *q;  // exactly the same as p!

const int foo();        // const is redundant here, nobody will care
const int *bar();       // but not here!
int *const baz();       // redundant again
const int *const zip(); // guess which of them is redundant

Zopotantor fucked around with this message at 08:57 on Jul 20, 2014

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

PS. Love the cabin posted:

Is there a way to call functions at an address including passing arguments without having to write a function prototype for each one?
libffi

You know how C/C++ lets you shoot yourself in the foot with extreme ease? This library lets you do it with a bazooka. Caveat emptor.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

eXXon posted:

I guess I may as well ask if it's true that there's a potentially meaningful performance difference between ++i and i++ in a for loop, if it's not optimized away at least.

I would think any C compiler written in the last 30 years will optimize i++ to ++i when it can (e.g., when the result is ignored).

Having said that, I have used at least one compiler that didn't, and to this day I prefer the prefix form. (Alcyon C on the Atari ST. Three passes plus assembler, with all intermediate files stored on (floppy!) disk. But it taught me so much... :corsair:)

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Jewel posted:

STL devs thought they were smart and made << and >> both insertion operators and bitshifting operators at the same time, depending on what the object they're used on's implementation of them is. For numbers it's a bitshift, for iostream/stringstream it's a concat operation, and for filestream it's.. I guess technically concat but more insertion. STL's design decisions are Not Very Good.

iostreams are pre-STL. Thank Bjarne for that poo poo; STL was a much needed improvement on prior C++ libraries.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

The Gay Bean posted:

Linux client and server: done in milliseconds.
Linux server and OSX client: Done in milliseconds.
OSX server and Linux/OSX client: I don't know how long, probably an hour.

I've controlled for TCP_NODELAY and blocking, and a blocking socket in Linux and OSX seem to behave completely differently. I can set the OSX socket to nonblocking mode, catch those -1 returns and retry until I've sent all my data; I guess this is what I'm supposed to do then? More to the point, is there some good, cross-platform wrapper for native socket functions, which all seem to behave differently in unexpected ways? Or do I just bandage it up with preprocessor macros?

You could use Wireshark to see what's actually going on.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Suspicious Dish posted:

strlcpy silently truncates and if your source isn't zero terminated it just starts poking everything.

If your source isn't zero terminated you've either already hosed up or you shouldn't be using str* functions anyway.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Fergus Mac Roich posted:

-Wall -pedantic for life.

Look at this poser who doesn't use -Werror. :colbert:

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

roomforthetuna posted:

gdb is the Linux command-line debugger, it's not much fun but it just about works. It's often easier to use the old-school option than it is to use gdb.

There's a GUI shell for gdb called "ddd" which is a bit easier to use.
http://www.gnu.org/software/ddd/

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

JawKnee posted:

I'm writing a couple of clients and a server for a networking class that requires that the server and clients be able to handle sending/receiving concurrently. This hasn't been a problem for my server, or my TCP client, however I've run into a snag with my UDP client.

UDP is a connectionless protocol. The receiver will not get a notification when the sender closes its socket, and recvfrom() will just wait endlessly.

The OS X man page of recvfrom() mentions this explicitly:

quote:

RETURN VALUES
These calls return the number of bytes received, or -1 if an error occurred.

For TCP sockets, the return value 0 means the peer has closed its half side of the connection.
I suspect that you get ENOTCONN from your shutdown() calls, you should probably check that.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Xerophyte posted:

The basic idea is that you have an untemplated base interface for your data holder that's then implemented by a template class that can hold any type. The any class itself stores a pointer to the base interface. Constructing an any object as well as getting the stored class back out will be templated, but the any class itself wont. The basic scheme is described here.

From that link:
code:

return result ? *result : throw std::bad_cast();
Holy cow. I've used C++ for 23 years, and I never knew that throw is an expression, not a statement. I may abuse the poo poo out of this now I know. :pervert:

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Slurps Mad Rips posted:

Using a throw in an expression was mentioned in C++11 I believe, otherwise it would be really hard to error out of constexpr functions. Most stuff like string_view must be implement several functions in terms of the ternary with a throw of implementing it in C++11 instead of C++14.

The proposal for exceptions in the ARM (Stroustrup & Ellis) already specified throw to be an expression. But it may never have been intended to be used in that way. (I don't think they intended templates to be Turing complete either.)

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

FamDav posted:

If you think of the expressible types in your type system, bottom is a subtype of all of those types. You can think of it as void, because any function that returns void returns nothing, except if I could actually assign the results of a void function.

It's magic because c and c++ don't have that kind of bottom, so you can't create your own throw.

Actually :eng101: void is the type that is called 'unit' in functional languages. Void functions return to their caller, but the 'value' they return is not used. Bottom is the conceptual return type of functions that don't return, not even a useless value.

C++ doesn't allow the unit value to be passed around, so you can't do this:
code:
void fart(void);
void butt(void);
void dick(void)
{
  return fart(butt()); // nope
}
The value of a throw expression is treated as void syntactically (I think; at least the description of the conditional expression treats it that way). This is about as theoretically consistent as the rest of C++, so nobody really cares (except for pedants like myself :eng99:).

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Frank Viola posted:

I'm trying to write a simple program that converts an entered number from 1 to 100 to roman numerals. We can't use recursion or arrays yet. The code compiles but It only prints "C" (100), regardless of the value entered for n. Why would this happen?

The comma operator does not do what you think it does.
You need to use && instead.

Oh, and your use of "return" also looks suspicious. You may want to replace it with "continue".

Zopotantor fucked around with this message at 19:46 on Jun 8, 2015

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

JawKnee posted:

Post the changes you made, if you change all returns to continue, and change the assignment operators in the if-statement-condition to the equality operator, as well as changing the commas to && (again in the if-condition) then it will work fine, the only time you would be stuck in the loop is if n is being set to something higher than 0 and not decremented to 0 in a reachable statement (I'm guessing you either missed an assignment operator or changed the assignment operator inside the if-block to an equality operator accidentally).

Check what happens if n is, e.g., 30.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Slash posted:

I'm surprised no one has attempted to do this as a one-liner yet.

Knuth needed 20 lines for it in TeX, so I'm not going to try.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Subjunctive posted:

That's no justification.

Justification takes even more code, man.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

DrSunshine posted:

Oh! So instead of "ballSet[i]" it'd be like "ballset[ballSet.size()]"? That had not occurred to me! Brilliant!

That is undefined behavior (out of bounds reference) if you're using a vector, and if you're lucky it will crash. (If you're unlucky, it will post your banking details to 4chan.)

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Doc Block posted:

I have a kinda weird question: why do so many C++ developers make their for loops use prefix increment instead of postfix increment?
For me, it's because the first C compiler I ever used was so lovely that it actually created worse code for postfix increment even with an integer index. (Alcyon C on the Atari ST :corsair:)

In C++, the postfix operator has to create a temporary value while the prefix operator can just return a reference to *this. Modern compilers should optimize the temporary away when it is not used, but some of us still don't trust them...

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

hackbunny posted:

CVS is a positively ancient revision control system.

In my first job we used SCCS. :corsair:

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

stochastastic posted:

Check your input file for control characters. For instance, repeated backspace control characters would cause something like this, e.g.
1, #yapbozmeb^H^H^H^H^H^H^H^H^H

More likely a CR (\r) if removing a single character fixes it. That might happen when reading in binary mode on Windows.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Rottbott posted:

:aaa: Every time I think I've finally learned everything about this language...!
https://www.youtube.com/watch?v=rNNnPrMHsAA

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

rjmccall posted:

Creating a new kernel-scheduled thread is actually a really expensive operation on almost every established operating system, but IIRC that's especially true on Windows.

I miss BeOS, where creating threads was so cheap that the general rule of thumb was, "when in doubt, spawn another thread." :eng99:

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Plorkyeran posted:

You can only partially specialize types and not functions, so to partially-specialize a function you have to make it a non-templated static member of a templated struct. You also have the syntax for partial specialization wrong; it's template<typename T> struct Bar<T, Foo> { ... }; to partially-specialize template<typename T, typename U> struct Bar;.

You could try to overload the function and use SFINAE (enable_if etc.) to select which version to use.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Shy posted:

I don't know if that's better suited for the general programming thread but I've been meaning to ask about C++ standard/compiler progress over the last 15-20 years. If I understand it correctly C++11 and newer is mostly supported across all modern compilers and performs well, but let's say 15 years ago would a team choosing it over C for a large project encounter many additional difficulties compared to now?
I'm not looking for a detailed answer (though if you have an article handy that would be cool), mostly just want to get an idea of how bad C++ compilers used to be compared to C. My C++ experience is reading the first 200 pages of the stroustrup book :downs:

15 years ago IIRC we already had the STL and (some) compilers that could handle it. 20 years ago you had cfront and whatever lovely class library your vendor supplied (I'm looking at you, HP codelibs :bahgawd:).

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Spatial posted:

I want to automatically generate minimal boolean expressions for the control signals coming out of an instruction decoder. The inputs to this algorithm are a table of all instructions and the corresponding control signals they need to set.

What's a good way to approach this kind of problem? A giant karnaugh map?

I'd also like zero redundancy in the expressions to minimise the size of the decoder.

That's a hard problem.

https://en.wikipedia.org/wiki/Espresso_heuristic_logic_minimizer

Adbot
ADBOT LOVES YOU

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

tractor fanatic posted:

Can I use CRTP to make mixin constructors? I don't think it's possible without UB but maybe there's hope:

C++ code:

template <class Der>
class stringable{
public: stringable(const std::string & s) { static_cast<this>(Der*)->intval = std::stoi(s); }
};

class D : public stringable<D>{
public:
	int intval;
	using stringable<D>::stringable;
};

For construction, it would be simpler (and completely legal) to do this, I think:
code:

class I { int intval; public: I(int i) : intval(i) {} };  // sorry about the layout, typing on tablet

template <typename D> class stringable : public D
{
public:
  stringable(string s) : D(std::stoi(s)) {}
};

stringable<I> foo("42");

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