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
Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

shodanjr_gr posted:

I got a programming pattern question.

I have an established library and for some (not all) of the exposed classes, I'd like to place proxies in front of them (in order to alter the functionality). For the components of the library that are not proxied, I'd like them to maintain their original functionality.

I'd like my proxy layer to offer the exact same interface as the library that it's sitting in front of (same namespaces, same symbols). The problem is that the proxy layer also has to link against the library itself so, if it exposes the exact same interface, i'll end up with symbol name conflicts.

Is there some elegant way to do this (without editing the source of the original library)?

If you're doing this on windows using visual studio, Detours can do this automatically.

Adbot
ADBOT LOVES YOU

hooah
Feb 6, 2006
WTF?
What is the best kind of data structure for doing a gradebook? I was thinking of a vector of vectors, but that runs into problems when I want the first inner vector to be a vector of strings but the rest to be doubles.

Rottbott
Jul 27, 2006
DMC
I don't know what a gradebook is or exactly what you want it to do, but it sounds like this:

code:
struct BookEntry
{
	string Name;
	vector<double> Grades;
};

vector<BookEntry> MyBook;
Does that look about right as a first stab?

hooah
Feb 6, 2006
WTF?

Rottbott posted:

I don't know what a gradebook is or exactly what you want it to do, but it sounds like this:

code:
struct BookEntry
{
	string Name;
	vector<double> Grades;
};

vector<BookEntry> MyBook;
Does that look about right as a first stab?

I think that might be a good start. Looks like I'll have to learn more about structs than just that they exist.

Acer Pilot
Feb 17, 2007
put the 'the' in therapist

:dukedog:

hooah posted:

I think that might be a good start. Looks like I'll have to learn more about structs than just that they exist.

A struct is basically a public class that just holds variables. There you go.

Hughlander
May 11, 2005

Are there any good things to read (books, blogs, magazine articles anything?) for an experienced C++03 developer wanting to learn what parts of C++11 are of daily use, vs what they should just be aware of in general? I know at a high level about a lot of them, but there's plenty of details I'm missing. Like when would you need to implement a move constructor. Or why you would want to invoke std::move vs just the assignment operator as two closely related examples.

hooah
Feb 6, 2006
WTF?

Hughlander posted:

Are there any good things to read (books, blogs, magazine articles anything?) for an experienced C++03 developer wanting to learn what parts of C++11 are of daily use, vs what they should just be aware of in general? I know at a high level about a lot of them, but there's plenty of details I'm missing. Like when would you need to implement a move constructor. Or why you would want to invoke std::move vs just the assignment operator as two closely related examples.

The newest version of the C++ Primer has a list of all the new stuff in the front, with what section the bits are covered by too.

KNITS MY FEEDS posted:

A struct is basically a public class that just holds variables. There you go.

Can I define a struct within a class header?

hooah fucked around with this message at 23:12 on Sep 7, 2013

nielsm
Jun 1, 2009



hooah posted:

Can I define a struct within a class header?

What the hell is a class header?

It sounds like something your IDE invented, it's certainly not a concept C++ deals with.

You can declare POD structs pretty much anywhere you want.


Actually, that just made me think. Can you do this?
C++ code:
std::vector<struct { int foo; }> v;
(Please say no.)

Rottbott
Jul 27, 2006
DMC
No.

hooah
Feb 6, 2006
WTF?

nielsm posted:

What the hell is a class header?

It sounds like something your IDE invented, it's certainly not a concept C++ deals with.

I meant in the header file. I tried it, and MSVC didn't complain.

Rottbott, for that example struct you gave, how would I assign values to Name and Grades?

bc87
Dec 11, 2010
I'm gonna dump code with absolutely no context.

code:
#include <iostream>
#include <string>
#include <map>
using namespace std;

int main(){

	string str;
	string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWSXYZabcdefghijklmnopqrstuvwxyz";
	map<char,int> char_map;
	int str_length = 0;
	int alphabet_length = alphabet.length();
	cout << "Input a string" << endl;
	getline(cin,str);
	str_length = str.length();

	for(int i = 0; i < str_length; i++){
		char_map[str[i]] += 1;
	}
	
	for(int i = 0;i < alphabet_length ; i++){
		if(char_map[alphabet[i]] != 0){
			cout << alphabet[i] << " = " << char_map[alphabet[i]] << endl;
		}
	}
	

	/*
	cout << "A = " << char_map['A'] << endl;
	cout << "B = " << char_map['B'] << endl;
	cout << "C = " << char_map['C'] << endl;
	cout << "D = " << char_map['D'] << endl;
	cout << "E = " << char_map['E'] << endl;
	cout << "F = " << char_map['F'] << endl;
	cout << "G = " << char_map['G'] << endl;
	cout << "H = " << char_map['H'] << endl;
	cout << "I = " << char_map['I'] << endl;
	cout << "J = " << char_map['J'] << endl;
	cout << "K = " << char_map['K'] << endl;
	cout << "L = " << char_map['L'] << endl;
	cout << "M = " << char_map['M'] << endl;
	cout << "N = " << char_map['N'] << endl;
	cout << "O = " << char_map['O'] << endl;
	cout << "P = " << char_map['P'] << endl;
	cout << "Q = " << char_map['Q'] << endl;
	cout << "R = " << char_map['R'] << endl;
	cout << "S = " << char_map['S'] << endl;
	cout << "T = " << char_map['T'] << endl;
	cout << "U = " << char_map['U'] << endl;
	cout << "V = " << char_map['V'] << endl;
	cout << "W = " << char_map['W'] << endl;
	cout << "X = " << char_map['X'] << endl;
	cout << "Y = " << char_map['Y'] << endl;
	cout << "Z = " << char_map['Z'] << endl;
	cout << "a = " << char_map['a'] << endl;
	cout << "b = " << char_map['b'] << endl;
	cout << "c = " << char_map['c'] << endl;
	cout << "d = " << char_map['d'] << endl;
	cout << "e = " << char_map['e'] << endl;
	cout << "f = " << char_map['f'] << endl;
	cout << "g = " << char_map['g'] << endl;
	cout << "h = " << char_map['h'] << endl;
	cout << "i = " << char_map['i'] << endl;
	cout << "j = " << char_map['j'] << endl;
	cout << "k = " << char_map['k'] << endl;
	cout << "l = " << char_map['l'] << endl;
	cout << "m = " << char_map['m'] << endl;
	cout << "n = " << char_map['n'] << endl;
	cout << "o = " << char_map['o'] << endl;
	cout << "p = " << char_map['p'] << endl;
	cout << "q = " << char_map['q'] << endl;
	cout << "r = " << char_map['r'] << endl;
	cout << "s = " << char_map['s'] << endl;
	cout << "t = " << char_map['t'] << endl;
	cout << "u = " << char_map['u'] << endl;
	cout << "v = " << char_map['v'] << endl;
	cout << "w = " << char_map['w'] << endl;
	cout << "x = " << char_map['s'] << endl;
	cout << "y = " << char_map['y'] << endl;
	cout << "z = " << char_map['z'] << endl;
	*/
	
}

Pseudoscorpion
Jul 26, 2011


hooah posted:

Rottbott, for that example struct you gave, how would I assign values to Name and Grades?

What I'd do is create a constructor for the struct in addition to the variables; it would look something like this:
code:
struct BookEntry
{
	string Name;
	vector<double> Grades;

	BookEntry(string name, double grade)
	{
		Name = name;
		Grades.push_back(grade);
	}
};
So a call of
code:
BookEntry("John Doe", 3.0);
would create a BookEntry with the Name field containing 'John Doe' and the first grade being 3.0.

Alternatively, you could manually initialize the values like so:
code:
BookEntry foo;
foo.Name = "John Doe";
foo.Grades.push_back(3.0);
I'm not a fan of this approach, since it's a little too C for my tastes, but whatever floats your boat.

Pseudoscorpion fucked around with this message at 05:48 on Sep 8, 2013

Rottbott
Jul 27, 2006
DMC
It's not really a C thing, there's nothing wrong with doing it that way. So long as the object is in a 'sensible' state after construction. In this particular case I'd probably use a constructor taking just the name, and fill in the grades later:

code:
struct BookEntry
{
	string Name;
	vector<double> Grades;

	explicit BookEntry(string name)
	: Name(name)
	{
	}
};
Since hooah is a beginner this may be unnecessarily complicated for now. Particularly explicit which is essential in this example. If I were doing it for real I'd probably add a second constructor taking an initializer list for grades, but let's not get carried away :). Here's how you'd use my constructor for comparison:

code:
BookEntry foo("John Doe");
foo.Grades.push_back(3.0);

vector<BookEntry> MyBook { foo };
And yes, you would put the struct declaration in a header file, say 'Gradebook.h'. If you do that, make sure you qualify names with std:: rather than putting 'using namespace std' into your header! You probably also want to put a typedef for the book itself:

code:
typedef std:vector<BookEntry> Gradebook;
Then at the point of usage (in a .cpp file), you would create one like this:

code:
Gradebook MyBook;
// Used to be vector<BookEntry> MyBook;

hooah
Feb 6, 2006
WTF?
Thanks, guys, that's quite helpful. I am indeed a beginner, having only taken a 6-week summer class so far (enrolled in a second at the moment, but it's only been a week or so). I'd heard lots of advice to have side projects to show recruiters for internships/jobs, so since my wife is a teacher, I decided to start a program to keep track of grades (even though she probably won't use it).

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I was thinking of taking my home project from VS2010 C++ project into a Linux environment of some kind. I'm doing some stuff with OpenCL and I have been dragging more and more Boost stuff in since 2010 doesn't have any of the new language features. I also feel like all the supporting libraries I use are more popular in Linux than Windows. I was hoping for some advice in getting as many of these features as possible:

1. Baby me on Makefiles. Generally, my biggest problem has been forgetting to add files to the Makefile when I add a new file to the project, so a helper for that does a lot for me.
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.

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.

evensevenone
May 12, 2001
Glass is a solid.
SublimeText2 with the SublimeClang plugin is pretty awesome too. The interface is more similar to standard GUI text editors as well (i.e. tabs, Ctrl-xcv) but it's still super-duper powerful. Ctrl-p (quickly load any file in your project by typing the name) and ctrl-shift-f (regex searching of the entire project) are super-handy in particular.

It's a text editor, not a full IDE though so you can't do things like step through with a debugger. gdb/lldb are pretty easy to pick up though and really amazingly nice though (although I don't know how well lldb does with c++)

Another thing I've been doing lately is using inotify-tools to have a shell script that runs 'make test' every time I save a file in my tree. I just leave that going on a second monitor, all the time, and just look at it out of the corner of my eye.

Look Around You
Jan 19, 2009

So I'm writing a game in C and considering rolling my own object/trait system for it and I'm wondering just how bad of an idea this is/if there's anything fundamentally wrong with how I'm thinking of implementing it.

My basic idea is to use a standard vtable for everything like so:

C++ code:
typedef void (*draw_fn)(void *);
typedef int (*hp_fn)(void *);
typedef void (*move_fn)(void *, point);
typedef void (*ai_fn)(void *); // only for npcs
// ...

typedef struct vtable {
	draw_fn draw;
	hp_fn get_hp;
	move_fn move;
	ai_fn ai;
	// ...
} vtable;
Then when making the objects, the structs would have that as their first member, since the first member of a struct is guaranteed to be at the starting address of the struct. Using the compound literal syntax from C99 makes it even easier, because if you don't implement something from the standard vtable, you just don't need to include it in the list, and it'll automatically be initialized to 0, which makes adding functionality to the global vtable easy (since I won't need to update any existing init functions just to init the new, unused method to 0).

C++ code:
typedef struct player {
	vtable vtbl;
	int hp;
	point loc;
	// ...
} player;

// assume prototypes are declared
void player_init(player *p)
{
	p->vtbl = (vtable) { .draw = player_draw, .get_hp = player_get_hp, .move = player_move };
	// other initialization here
}

typedef struct monster {
	vtable vtbl;
	int hp;
	point loc;
	ai_type ai;
} monster;

void monster_init(monster *m)
{
	m->vtbl = (vtable) { .draw = monster_draw, .get_hp = monster_get_hp, .move = monster_move, .ai = monster_ai };
	// ...
}

And I'd be able to write generic functions like so:

C++ code:
int get_hp(void *v_self)
{
	vtable *self = v_self;
	// check if it's implemented (it's null if not)
	if (self->get_hp) {
		hp_fn meth = self->get_hp;
		return meth(self);
	} else {
		// handle method missing
	}
}

int monster_get_hp(void *v_self)
{
	monster *self = v_self;
	return self->hp;
}
int player_get_hp(void *v_self)
{
	player *self = v_self;
	return self->hp;
}
and then I can call them like this:

C++ code:
void do_something(monster *m)
{
	if (get_hp(m) > 30) {
		move(m, (point) {.x = 59, .y = 349 });
	}
}
Obviously having a global vtable with literally every method isn't really optimal (especially as the project gets bigger), so I'm trying to figure out a way around that, but so far this seems like it'd work.

I'm kinda posting this here to see if anyone has input on this, like if I'm missing anything obvious or if anyone has any suggestions (or to see if I'm crazy).

Note: I don't want to write it in C++. I just don't. I know it'd be easier in C++, but I wanted to write something in plain C.

Look Around You fucked around with this message at 05:39 on Sep 9, 2013

Rottbott
Jul 27, 2006
DMC
By having a copy of the full vtable in every object, you're making them much larger unnecessarily. C++ objects store a pointer to a vtable instead, it's an extra indirection when calling methods, but you only need one global copy of each unique vtable layout (e.g. monster, player). I would do it that way to begin with.

If you want to get fancy, Andrei Alexandrescu's recent talk at GoingNative had interesting stuff about DIY vtables - he's talking C++ but the code is essentially C. See here, in particular the slide about 'vertical tables' at 42:00.

Doctor w-rw-rw-
Jun 24, 2008
Having a weird issue that someone can probably enlighten me on real quick.

See: https://github.com/toulouse/ATLeagueUtility/blob/master/src/main.cpp#L36
Without the "new" on line 36, I get an error: "Call to implicitly-deleted copy constructor of 'AT::RAF::Archive".

The constructor is defined as "Archive(const string &archiveFilename);", which shouldn't be a copy constructor, right? Even with "Archive(const Archive &) = default;" added on to the Archive class's declaration, it seems to think the copy constructor has been implicitly deleted, and that the call to it is invalid. What's going on? Does C++ have problems overloading constructors that take a reference type?

limip
Oct 24, 2003

Doctor w-rw-rw- posted:

Having a weird issue that someone can probably enlighten me on real quick.

See: https://github.com/toulouse/ATLeagueUtility/blob/master/src/main.cpp#L36
Without the "new" on line 36, I get an error: "Call to implicitly-deleted copy constructor of 'AT::RAF::Archive".

The constructor is defined as "Archive(const string &archiveFilename);", which shouldn't be a copy constructor, right? Even with "Archive(const Archive &) = default;" added on to the Archive class's declaration, it seems to think the copy constructor has been implicitly deleted, and that the call to it is invalid. What's going on? Does C++ have problems overloading constructors that take a reference type?
For explicitness I assume that you mean:
code:
auto archive = Archive(archiveFilename);
fails?

In this case, the copy constructor is implicitly deleted since the member ifstream is non-copyable, and that syntax requires a copy (or move) constructor to be available (even if it may not be called by the compiler). I'm almost positive that ifstream is moveable, though, so depending on your comfort with move operations, saying "Archive(Archive&&) = default;". But unless you're secretly Herb Sutter and have a crazy obsession with using auto for everything, "Archive archive(archiveFilename);" would work just as well.

Doctor w-rw-rw-
Jun 24, 2008

limip posted:

For explicitness I assume that you mean:
code:
auto archive = Archive(archiveFilename);
fails?

In this case, the copy constructor is implicitly deleted since the member ifstream is non-copyable, and that syntax requires a copy (or move) constructor to be available (even if it may not be called by the compiler). I'm almost positive that ifstream is moveable, though, so depending on your comfort with move operations, saying "Archive(Archive&&) = default;". But unless you're secretly Herb Sutter and have a crazy obsession with using auto for everything, "Archive archive(archiveFilename);" would work just as well.

Yes, that's what I mean, and I'm afraid I don't quite understand. How is Archive(ifstream) a copy constructor if it's not even an Archive, or am I misunderstanding what a copy constructor is? I'm approaching this from a background in C/ObjC,Java/etc., so I'm positive I have a hole in my knowledge.

(I did take your advice to fix it, though, thanks!)

nielsm
Jun 1, 2009



Doctor w-rw-rw- posted:

Yes, that's what I mean, and I'm afraid I don't quite understand. How is Archive(ifstream) a copy constructor ifkp it's not even an Archive, or am I misunderstanding what a copy constructor is? I'm approaching this from a background in C/ObjC,Java/etc., so I'm positive I have a hole in my knowledge.

(I did take your advice to fix it, though, thanks!)

Your Archive class likely holds an ifstream object as member. The default copy constructor copies all members of the class one by one. If one of the members can't be copied then the compiler can't generate the default copy constructor. The ifstream class can't be copied, therefore an Archive class with one as member can't have a default copy constructor.
(Sorry about going all basic logic here, but I hope it explains. At least it's how I understood it.)

seiken
Feb 7, 2005

hah ha ha

nielsm posted:

Your Archive class likely holds an ifstream object as member. The default copy constructor copies all members of the class one by one. If one of the members can't be copied then the compiler can't generate the default copy constructor. The ifstream class can't be copied, therefore an Archive class with one as member can't have a default copy constructor.
(Sorry about going all basic logic here, but I hope it explains. At least it's how I understood it.)

The problem was the the poster didn't understand why a copy constructor would be needed at all. The distinction is the = used in the variable declaration.
C++ code:
auto archive = Archive(archiveFilename);
C++ code:
Archive archive(archiveFilename);
These two statements, in most cases, do the same thing. But what the first really does is to create a temporary Archive and then uses it to copy-construct archive, rather than directly constructing archive. I think sometimes this may be optimised away depending on how simple the type is, but nevertheless if you use the first statement the copy-constructor must exist and be accessible.

seiken fucked around with this message at 10:54 on Sep 10, 2013

Slurps Mad Rips
Jan 25, 2009

Bwaltow!

seiken posted:

The problem was the the poster didn't understand why a copy constructor would be needed at all. The distinction is the = used in the variable declaration.
C++ code:
auto archive = Archive(archiveFilename);
C++ code:
Archive archive(archiveFilename);
These two statements, in most cases, do the same thing. But what the first really does is to create a temporary Archive and then uses it to copy-construct archive, rather than directly constructing archive. I think sometimes this may be optimised away depending on how simple the type is, but nevertheless if you use the first statement the copy-constructor must exist and be accessible.

That is incorrect. That first expression should use a move constructor at most, and a default initialization at least.
(as the expression on the right is an rvalue) unless the compiler being used is some visual studio version in which case ignore me, as visual studio doesn't follow the new standard.

EDIT: wow, I double quoted somehow?

Slurps Mad Rips fucked around with this message at 20:32 on Sep 10, 2013

Doctor w-rw-rw-
Jun 24, 2008
Nope, LLVM 3.3 on C++11 with libc++.

Enlightening stuff. Thanks!

Illusive Fuck Man
Jul 5, 2004
RIP John McCain feel better xoxo 💋 🙏
Taco Defender
I'm writing a thing. It forks and execs stuff. It will join children if they terminate before the parent, but otherwise I just want it to ignore them.
The child does:
code:
pid = fork();
if( !pid ) {
	//redirect stdout and stderr to some file
	fd = open(some_file, O_CREAT | O_WRONLY | O_APPEND, 0644);
	dup2(fd, 1);
	dup2(fd, 2);
	execve(some_exe, argv, envp);
}
I left out some error checking code and stuff but you get it. All of this works fine. The problem is that it does some weirdo poo poo to the terminal. After a fork/exec, I can no longer Ctrl-c the parent. I think the terminal's input is being sent to the children? If I signal the parent from somewhere else, it gets handled fine and closes (the children are still running. This is what I want). After it has closed, I can type in the original terminal, but no characters appear. eg, if I type asdf<enter>, I get:

[user@whatever dir]# -bash: asdf: command not found
[user@whatever dir]#

Instead of:

[user@whatever dir]# asdf
-bash: asdf: command not found
[user@whatever dir]#

Messing around trying to fix this, I added a close(0) before execve() to close stdin. This fixes all the terminal weirdness, and I can Ctrl-c the parent, but it takes the children down with it! If I signal the parent from somewhere else, the children keep on truckin.

What have I most likely hosed up?

The Laplace Demon
Jul 23, 2009

"Oh dear! Oh dear! Heisenberg is a douche!"
Here's code demonstrating standard C++11 behavior: http://coliru.stacked-crooked.com/a/021dbd912b88f189
Note that the copy constructor of ContainsMoveOnly is implicitly deleted due to having a member of type MoveOnly

Not sure what the issue is if you're compiling with LLVM 3.3 using the "-std=c++11" flag. I'm stuck with LLVM 3.2svn and the code I posted above compiles just fine. (it only complains about unused variables)

EDIT: You've defined a copy constructor/operator in your class. Define a move constructor/operator, and the problem should go away.

EDIT 2: No, it won't. Your version of libc++ isn't standards compliant. std::ifstream is move-constructable, but it wasn't in older versions. If you download the latest version, it should compile fine.

The Laplace Demon fucked around with this message at 20:05 on Sep 10, 2013

Marta Velasquez
Mar 9, 2013

Good thing I was feeling suicidal this morning...
Fallen Rib

Illusive gently caress Man posted:

Messing around trying to fix this, I added a close(0) before execve() to close stdin. This fixes all the terminal weirdness, and I can Ctrl-c the parent, but it takes the children down with it! If I signal the parent from somewhere else, the children keep on truckin.

What have I most likely hosed up?

When you fork(), the children inherit a copy of the parent's file descriptors, so the children may have been grabbing your terminal from you when they inherited fd 0.

As for Ctrl+C, this looks like what normally happens. It sounds like you're not catching SIGINT to override the normal behavior, except for when you mentioned signaling from somewhere else. How are you signaling the parent otherwise?

Illusive Fuck Man
Jul 5, 2004
RIP John McCain feel better xoxo 💋 🙏
Taco Defender

contrapants posted:

When you fork(), the children inherit a copy of the parent's file descriptors, so the children may have been grabbing your terminal from you when they inherited fd 0.

As for Ctrl+C, this looks like what normally happens. It sounds like you're not catching SIGINT to override the normal behavior, except for when you mentioned signaling from somewhere else. How are you signaling the parent otherwise?

I have a handler for SIGINT/SIGTERM, so I just use kill in another terminal. Obviously when the children execve, they lose that handler (which is what I want anyway).

What do you mean by 'what normally happens' regarding Ctrl-C? Why are children responding to Ctrl-C after I close fd 0? Is closing fd 0 the right way to do this? Should I open /dev/null and dup it to 0 instead?

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

Illusive gently caress Man posted:

Why are children responding to Ctrl-C after I close fd 0? Is closing fd 0 the right way to do this? Should I open /dev/null and dup it to 0 instead?

Signals don't come through stdin, you need to detach the children from the controlling terminal, eg. with setsid

Illusive Fuck Man
Jul 5, 2004
RIP John McCain feel better xoxo 💋 🙏
Taco Defender

hackbunny posted:

Signals don't come through stdin, you need to detach the children from the controlling terminal, eg. with setsid

Thanks, that's exactly what I needed.

That Turkey Story
Mar 30, 2003

SAHChandler posted:

This is incorrect, and only applies to c++03 or compilers that lack uniform initialization.
It is still allowed to be optimized away in C++03 and C++11, and compilers do so (it also doesn't matter how complicated the type or its copy/move is). The appropriate constructor still needs to be able to be called though.

SAHChandler posted:

For instance, lambdas are noncopyable, so in the case of the first expression, were it to be a lambda it would simply not compile.
What? Lambdas are copyable. In fact, just about every time you use them you are copying them, since most proper algorithms take the function object by value.

SAHChandler posted:

That is incorrect. That first expression should use a move constructor at most, and a default initialization at least.
(as the expression on the right is an rvalue) unless the compiler being used is some visual studio version in which case ignore me, as visual studio doesn't follow the new standard.
No. Seiken really is correct. A compliant compiler is allowed to optimize away the copy or move operation and construct the object in place.

The Laplace Demon
Jul 23, 2009

"Oh dear! Oh dear! Heisenberg is a douche!"

That Turkey Story posted:

No. Seiken really is correct. A compliant compiler is allowed to optimize away the copy or move operation and construct the object in place.

This is correct. To elaborate, auto x = MyClass{}; or auto x = MyClass(); will construct MyClass using MyClass::MyClass(), and then using either the copy/move constructor/operator, will copy/move it into x.

If the user hasn't defined any copy/move constructors/operators, the prvalue will be moved into x assuming all members of MyClass are moveable types. If not, then it will be copied if all members are copyable types. If not, you get an error.

If the user has defined a copy constructor/operator, the prvalue will be copied into x using that. If it is the default, this only occurs if all types are copyable. Otherwise, you get an error.

If the user has defined a move constructor/operator, the prvalue will be moved into x using that. If it is the default, this only occurs if all types are moveable. Otherwise, you get an error.

If the user has defined both copy and move, then the prvalue is moved. In practice, the compiler will probably just construct your type in place. But both copy and move cannot be deleted, explicitly or implicitly.

EDIT: nothing to see here

The Laplace Demon fucked around with this message at 20:05 on Sep 10, 2013

Slurps Mad Rips
Jan 25, 2009

Bwaltow!

That Turkey Story posted:

It is still allowed to be optimized away in C++03 and C++11, and compilers do so (it also doesn't matter how complicated the type or its copy/move is). The appropriate constructor still needs to be able to be called though.

What? Lambdas are copyable. In fact, just about every time you use them you are copying them, since most proper algorithms take the function object by value.

No. Seiken really is correct. A compliant compiler is allowed to optimize away the copy or move operation and construct the object in place.

I somehow managed to post the one response that I realize was wrong (about the lambdas). I could have sworn I deleted it (was posting from the awful app), but it went through anyhow. That explains the double quote.

I know they can optimize it away, but I believe I had read the message where most cases wasn't in the message (I definitely don't remember it being there). Basically I hosed up, ignore what I said :v:

Doctor w-rw-rw-
Jun 24, 2008
More confusion, this time over how to read only a specific range of an ifstream.

C++ code:
        // file is an ifstream
        void Archive::readFile(const File &f, const ostream& output) {
            stringstream rawContents;
            file.seekg(f.getDataOffset());
            istream_iterator<char> is(file);
            copy_n(is, f.getDataSize(), ???);

            filtering_streambuf<boost::iostreams::input> in;
            in.push(zlib_decompressor());
            in.push(rawContents);

            boost::iostreams::copy(in, output);
        }
Basically I have a offset and a size that refers to a gzip-encoded file inside an archive. I want to read this range, decode it, then either return it or read it into a buffer of the caller's choosing (either would be fine, whichever is easier or better to implement).

I have no clue what arguments to feed to copy_n to make it work, or whether this is the right approach in the first place. Should I just be reading into a char vector and back out?


EDIT: After stepping away I wonder if I should just use the ifstream to read into a vector instead of doing this stupid crap with streams, because it'd have to allocate the same or more amount of memory anyway to convert it from gzip to raw. Should get me most of the way to the next error in my code...

EDIT 2: I am at a complete loss for how to decompress the bytes into another vector array. :/

EDIT 3: nevermind, got it: https://github.com/toulouse/ATLeagueUtility/commit/9ac9069c1afe7adfa2b8b8023e87e9dcc3fe3c70. It feels like C++ will never get any easier :qq:

Doctor w-rw-rw- fucked around with this message at 09:02 on Sep 11, 2013

Mr.Radar
Nov 5, 2005

You guys aren't going to believe this, but that guy is our games teacher.
Edit: wrong thread.

more like dICK
Feb 15, 2010

This is inevitable.
Are there any good JSON libs for C?

MrMoo
Sep 14, 2000

I'd have a look at https://wiki.gnome.org/JsonGlib/ if you don't mind bringing in Glib land.

Adbot
ADBOT LOVES YOU

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
JSON GLib is an amazing library, if only for its integration with GVariant, which is kick-rear end.

But if you're not a glib fan it's probably not for you.

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