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
6174
Dec 4, 2004

ColdPie posted:

Not to mention traversing directories and making makefiles for each directory. Eclipse does a pretty good job of making makefiles, in my opinion.

Recursie Make Considered Harmful. In my opinion, the paper goes a little far as there are sometimes reasons to use make recursively, but more often than not it is abused which slows down the build process unnecessarily.

Adbot
ADBOT LOVES YOU

more falafel please
Feb 26, 2005

forums poster

HB posted:

What about a project with 40 source files and multiple targets?

At some point you just want to let the computer take care of it.

He's just getting started, I doubt that's going to happen. At any rate, I think one of the reasons you should use make is to learn when you shouldn't :)

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

Peanutmonger posted:

I probably am. I also probably haven't used autotools well enough to get out of the "honeymoon" phase of how wonderful it is that configure will discover everything for me and build a Makefile with all of the targets I've come to expect. I really enjoyed doing a "make dist" and copying that to my other desktop and building it.

Using stuff that's already written to use autotools is great, yeah. Setting up your project to use autotools is a huge, huge pain in the rear end.

I like SCons myself, though I haven't used at enough to find the inevitable flaws.

Red Oktober
May 24, 2006

wiggly eyes!



Thanks for the input, I'll probably just stick with doing it manually but using xcode for the syntax colouring.

(My reason for wanting to use an IDE was that the vast amount of generated code was making it tricky to do it by hand, and I'm more concerned about getting this project in than learning C at the minute.)

very
Jan 25, 2005

I err on the side of handsome.
I've been driving myself nuts for a few days just trying to set up a simple callback. I think I need some Barney-level help. I have two questions:

Firstly, this is the simplest kind of callback class that I have found:

code:
template < class Class, typename ReturnType>
class GUIButtonCallback < Class, ReturnType >
{

   public:

    typedef ReturnType (Class::*Method)(void);

    GUIButtonCallback(Class* _class_instance, Method _method)
    {
       class_instance = _class_instance;
       method         = _method;
    }

    ReturnType operator()()
    {
       return (class_instance->*method)();
    }

    ReturnType execute()
    {
       return operator()();
    }

    private:

      Class*  class_instance;
      Method  method;

};
But this does not compile as-is. It will compile if I remove the < Class, ReturnType > after the class name, and I am not sure why that stuff is there anyway. It looks like a specialization, but why is it specializing in whatever the template specifies?

Second question:

code:
class GUIButton : public GUIControl
{
public:
	GUIButton(void);
	virtual ~GUIButton(void);

	// ...

private:

/* I don't want to specify a type here, because I have no idea what type 
of object this is going to be calling, I just want to be able to call anything! */
	GUIButtonCallback<?????, void> * m_callback;
};
With this scenario, is the callback class that I posted above even going to work? Should I just make it a void pointer? That seems to defeat the purpose and I don't know if that would work anyway.

citsejam
Dec 24, 2005

<3
If I disable certain signals in a parent process with sigignore, will I be able to use them in a child process if I use sigset to re-enable them in the child's code?

haveblue
Aug 15, 2005



Toilet Rascal

citsejam posted:

If I disable certain signals in a parent process with sigignore, will I be able to use them in a child process if I use sigset to re-enable them in the child's code?

That should work, yes. fork() gives the new process an independent signal mask (initialized to the current value of the parent's). At least, that's how it works in posix- I don't have a manpage for "sigignore" so I assume you're on something else.

haveblue fucked around with this message at 02:50 on Mar 2, 2008

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

very posted:

I've been driving myself nuts for a few days just trying to set up a simple callback. I think I need some Barney-level help. I have two questions:

Firstly, this is the simplest kind of callback class that I have found:

code:
template < class Class, typename ReturnType>
class GUIButtonCallback < Class, ReturnType >
{
...

};
But this does not compile as-is. It will compile if I remove the < Class, ReturnType > after the class name, and I am not sure why that stuff is there anyway. It looks like a specialization, but why is it specializing in whatever the template specifies?

You can't specialize 0 of the template parameters, so it's not a specialization at all. :) (i.e. remove <Class, ReturnType>)

very posted:

code:
/* I don't want to specify a type here, because I have no idea what type 
of object this is going to be calling, I just want to be able to call anything! */
	GUIButtonCallback<?????, void> * m_callback;
With this scenario, is the callback class that I posted above even going to work? Should I just make it a void pointer? That seems to defeat the purpose and I don't know if that would work anyway.

Make a base class for GUIButtonCallback to inherit from and use virtual functions. That is,
code:
template<typename ReturnType>
class GUIButtonCallbackBase
{
	//...
};

template <typename Class, typename ReturnType>
class GUIButtonCallback : public GUIButtonCallbackBase<ReturnType>
{
	//...
};

class GUIButton : public GUIControl
{
	//...
	GUIButtonCallbackBase<void> * m_callback;
};

very
Jan 25, 2005

I err on the side of handsome.

Avenging Dentist posted:

You can't specialize 0 of the template parameters, so it's not a specialization at all. :) (i.e. remove <Class, ReturnType>)
I thought so.

Avenging Dentist posted:

Make a base class for GUIButtonCallback to inherit from and use virtual functions. That is,
Thank you. It seems obvious now.

cronio
Feb 15, 2002
Drifter
If you want a more generic solution, check out http://nocturnal.insomniacgames.com/index.php/Common#Automation.2FEvent.h

It's part of our new opensource initiative, Nocturnal. You can download the code from http://nocturnal.insomniacgames.com/releases/Common/

Other options include FastDelegate (which ours is based on) -- http://www.codeproject.com/KB/cpp/FastDelegate.aspx, and boost::bind.

[edited for comma in URL]

cronio fucked around with this message at 21:12 on Mar 2, 2008

FigBug
Apr 27, 2002

Lemon Party - Lest we Forget
Are there any free or cheap profilers for windows?

ehnus
Apr 16, 2003

Now you're thinking with portals!

FigBug posted:

Are there any free or cheap profilers for windows?

AMD's Code Analyst is pretty good and completely free: http://developer.amd.com/tools/codeanalystwindows/Pages/default.aspx

oldkike
Jan 10, 2003

hey

www.pleasegimmeadollar.com

cronio posted:

If you want a more generic solution, check out http://nocturnal.insomniacgames.com/index.php/Common#Automation.2FEvent.h

It's part of our new opensource initiative, Nocturnal. You can download the code from http://nocturnal.insomniacgames.com/releases/Common/

Other options include FastDelegate (which ours is based on) -- http://www.codeproject.com/KB/cpp/FastDelegate.aspx, and boost::bind.

If you want a really generic solution, check out libsigc++. It supports multiple args to callbacks all with type-safety.

cronio
Feb 15, 2002
Drifter

oldkike posted:

If you want a really generic solution, check out libsigc++. It supports multiple args to callbacks all with type-safety.

How is this more generic than FastDelegate? (I don't know much about boost::bind, so I won't ask about it)

The support for Rebinding/Retyping doesn't seem compelling to me, since I prefer callbacks to be single-purpose (if the code needs to happen from multiple execution paths, I'd prefer the callback(s) call another function that does the work, rather than have a single callback that is rebinded/retyped).

Marshalling seems like it could be useful, but I can't think of any time I've actually needed that functionality.

Anyway, I'm not trying to knock libsigc++, I'm genuinely curious.

Thug Bonnet
Sep 22, 2004

anime tits ftw

What is a reasonable way to read a series of lines of unknown length that contain variables of mixed types from a text file? I have read that fprintf() can cause problems, and then there's the issue of buffer size. I could go ahead and make the buffer the size of the entire file for safety but that seems silly. On the other hand, seeking to the next newline and realloc()-ing the buffer for every line seems costly.

Lets assume the text file looks like this

code:
var1=1.0
var2=foo
..
e: In C, so no streams for me.

Thug Bonnet fucked around with this message at 22:10 on Mar 2, 2008

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Thug Bonnet posted:

On the other hand, seeking to the next newline and realloc()-ing the buffer for every line seems costly.

You'd only need to realloc when the next line is longer than the current one. If you pick a decent starting buffer length, there shouldn't be much reallocation.

Thug Bonnet
Sep 22, 2004

anime tits ftw

Avenging Dentist posted:

You'd only need to realloc when the next line is longer than the current one. If you pick a decent starting buffer length, there shouldn't be much reallocation.

Good point! Is that a reasonable thing to do then? I'm pretty new with file i/o so I honestly don't know.

cronio
Feb 15, 2002
Drifter

Thug Bonnet posted:

Good point! Is that a reasonable thing to do then? I'm pretty new with file i/o so I honestly don't know.

It's reasonable. If your files aren't going to be large though (if you're on a PC, on the order of tens of megabytes), reading the entire file and doing all the parsing in-memory is actually a better (faster) solution.

I'm used to C++, so this may not be perfectly valid C (variable declarations need to go to the top of the function for example).

code:
fseek( f, 0, SEEK_END );
int fileSize = ftell( f );
fseek( f, 0, SEEK_SET );

char* buf = (char*)malloc(fileSize);
fread( buf, 1, fileSize, f );

... parse ...

free( buf );
[edit] As far as string parsing goes in C, it basically sucks. atoi/atof/etc. are your friends, just make sure your strings are NULL terminated. The sn_ functions (snprintf, snscanf, etc.) are also handy (if your compiler supports them -- I'm not sure if they're standardized or not), since they take the size of the buffer, and so won't ever read off the end.

cronio fucked around with this message at 23:20 on Mar 2, 2008

crazypenguin
Mar 9, 2005
nothing witty here, move along

Thug Bonnet posted:

that contain variables of mixed types

Do you know the general format? fscanf might be quite useful.

oldkike
Jan 10, 2003

hey

www.pleasegimmeadollar.com

cronio posted:

How is this more generic than FastDelegate? (I don't know much about boost::bind, so I won't ask about it)

The support for Rebinding/Retyping doesn't seem compelling to me, since I prefer callbacks to be single-purpose (if the code needs to happen from multiple execution paths, I'd prefer the callback(s) call another function that does the work, rather than have a single callback that is rebinded/retyped).

Marshalling seems like it could be useful, but I can't think of any time I've actually needed that functionality.

Anyway, I'm not trying to knock libsigc++, I'm genuinely curious.

I was referring to the first link. The FastDelegate link was broken, but I googled it and saw that it was pretty equivalent to libsigc++. One nice thing about libsigc++ is that GTK uses it, so if you're using it in the application you can tie the GUI to everything without adapters and wrappers..

oldkike
Jan 10, 2003

hey

www.pleasegimmeadollar.com

cronio posted:

It's reasonable. If your files aren't going to be large though (if you're on a PC, on the order of tens of megabytes), reading the entire file and doing all the parsing in-memory is actually a better (faster) solution.

I'm used to C++, so this may not be perfectly valid C (variable declarations need to go to the top of the function for example).

code:
fseek( f, 0, SEEK_END );
int fileSize = ftell( f );
fseek( f, 0, SEEK_SET );

char* buf = (char*)malloc(fileSize);
fread( buf, 1, fileSize, f );

... parse ...

free( buf );
[edit] As far as string parsing goes in C, it basically sucks. atoi/atof/etc. are your friends, just make sure your strings are NULL terminated. The sn_ functions (snprintf, snscanf, etc.) are also handy (if your compiler supports them -- I'm not sure if they're standardized or not), since they take the size of the buffer, and so won't ever read off the end.

atoi, atof, etc are deprecated. Look at strtol, strtod, etc.

cronio
Feb 15, 2002
Drifter

oldkike posted:

atoi, atof, etc are deprecated. Look at strtol, strtod, etc.

Good to know, thanks.

Red Oktober
May 24, 2006

wiggly eyes!



I'm having a problem which I can't seem to sort out.

If I take a piece of code like this:

code:
case is_Stm:	
        char *str;
	str = (char *)calloc(strlen(visitIdent(_p_->u.stm_.ident_))+2, sizeof(char));
	strcpy(str, "_");
	strcat(str, (visitIdent(_p_->u.stm_.ident_)));
	return str;
    break;
The compile fails, whilst

code:
case is_Stm:	
       [b] printf("\n");[/b]
        char *str;
	str = (char *)calloc(strlen(visitIdent(_p_->u.stm_.ident_))+2, sizeof(char));
	strcpy(str, "_");
	strcat(str, (visitIdent(_p_->u.stm_.ident_)));
	return str;
    break;
Succeeds. It seems to fail whenever I try and declare something at the top of a block of code. Putting a statement like print about that sorts it.

I've tested this by trying to compile simclist into my project as well, and it fails for the same reasons.

Exact error is "error: syntax error before ‘char’" (if char is what I'm trying to declare.)

I'm using gcc 4.0.1, on mac os x leopard.

Any ideas?

cronio
Feb 15, 2002
Drifter
Honestly I'm not sure why either would compile. I've always thought that if you want to declare a variable inside a case statement, you need to give it scope:

code:
case is_Stm:
  {
    ...
  }
  break; // can be in or out of the brackets

pseudorandom name
May 6, 2007

Red Oktober posted:

I've tested this by trying to compile simclist into my project as well, and it fails for the same reasons.

Exact error is "error: syntax error before ‘char’" (if char is what I'm trying to declare.)

I'm using gcc 4.0.1, on mac os x leopard.

Any ideas?

The C grammar doesn't allow it.

labeled-statements are composed of labels followed by statements and declarators aren't statements.

You've discovered one ramification of this, another is that things like
code:
void fn()
{
    goto label;
    label:
}
also won't compile while
code:
void fn()
{
    goto label;
    label: [b];[/b]
}
will.

oldkike
Jan 10, 2003

hey

www.pleasegimmeadollar.com
C and C++ are so weird sometimes. Here's another syntax weirdness:

Valid C++:
code:
int main(int argc, char **argv)
try
{
  std::cout << "hello world" << endl;
} catch (...) {
  std::cout << "..." << endl;
}
Edit: Another, this evaluates differently in C and C++

code:
printf("%d\n",sizeof 1 ? "ab" : "cd");

oldkike fucked around with this message at 05:54 on Mar 3, 2008

pseudorandom name
May 6, 2007

oldkike posted:

C and C++ are so weird sometimes. Here's another syntax weirdness:
Speaking of weird, nothing tops Duff's Device:
code:
send(to, from, count)
register short *to, *from;
register count;
{
    register n = (count + 7) / 8;
    switch (count % 8) {
    case 0: do { *to = *from++;
    case 7:      *to = *from++;
    case 6:      *to = *from++;
    case 5:      *to = *from++;
    case 4:      *to = *from++;
    case 3:      *to = *from++;
    case 2:      *to = *from++;
    case 1:      *to = *from++;
               } while (--n > 0);
    }
}

pseudorandom name fucked around with this message at 09:17 on Mar 3, 2008

Red Oktober
May 24, 2006

wiggly eyes!



Ah, I see. I guess I'll work on keeping everything where it 'should' be, rather than kludging it then.

Neslepaks
Sep 3, 2003

quote:

code:
char* buf = (char*)malloc(fileSize);
code:
str = (char *)calloc(strlen(visitIdent(_p_->u.stm_.ident_))+2, sizeof(char));

Don't do these casts when writing C. void pointers are always implicitly castable to other pointers, all you'll achieve is to hide warnings you'd want to see (like if you forgot to include the prototype for malloc, or there's a more serious type mismatch).

Lexical Unit
Sep 16, 2003

In C++ I'm wondering what's standard operating procedure when defining a class's typedef for size_type. In other words, if I have a template class which is a container for typename T and I want to define container<T>::size_type, what's the best thing to do?

I considered typedef typename T::size_type size_type; but that doesn't work if T is int, for example. So then I considered using std::char_traits somehow because typedef typename std::char_traits<T>::int_type size_type; seems to work, but that could just be coincidental.

It looks like gcc's implementation of the STL mostly just uses std::size_t, but say I use typedef size_t size_name; and I have a method that returns a size_type and then the container is instantiated with some_crazy_string which uses some_crazy_size_type as it's some_crazy_string::size_type typedef and some_crazy_size_type is incompatible with std::size_t... then I've got a bug, right?

Edit: Or, is the best option to add another template parameter called SizeT and make it default to typename T::size_type, then use typedef SizeT size_type;?

Lexical Unit fucked around with this message at 00:57 on Mar 5, 2008

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Just use std::size_t. I'm not 100% sure what you're worried about, but size_t is perfectly acceptable, and it's not like the STL avoids it because they were too lazy to add another template argument. :)

tef
May 30, 2004

-> some l-system crap ->
Also,

[code]
str = (char *)calloc(strlen(visitIdent(_p_->u.stm_.ident_))+2, sizeof(char));

Should be:
str = malloc(strlen(visitIdent(_p_->u.stm_.ident_))+2);
[code]

As sizeof(char) is always 1.

more falafel please
Feb 26, 2005

forums poster

tef posted:

Also,

[code]
str = (char *)calloc(strlen(visitIdent(_p_->u.stm_.ident_))+2, sizeof(char));

Should be:
str = malloc(strlen(visitIdent(_p_->u.stm_.ident_))+2);
[code]

As sizeof(char) is always 1.

calloc() initializes memory to 0, while the contents of memory returned by malloc() are unspecified. Other than that, though, they're equivalent.

Lexical Unit
Sep 16, 2003

Avenging Dentist posted:

Just use std::size_t. I'm not 100% sure what you're worried about, but size_t is perfectly acceptable, and it's not like the STL avoids it because they were too lazy to add another template argument. :)
Contrived example ahoy!
code:
#include <iostream>
#include <set>

struct weird_thing {
	// ... insert insanity here ...

	typedef double size_type;

	weird_thing() {
		// Generate some crazy example sizes that might occur:
		static double z = 0;
		z += .2;
		size_ = z;
	}
	
	double size() const {
		return size_;
	}
	
	private:
		size_type size_;
};

template<typename T>
struct container {
	typedef std::size_t size_type;			// Gives BAD answer
//	typedef typename T::size_type size_type;	// Would give the correct answer
	
	// Lets say for some crazy reason we want the size of all items
	// totaled up as a method of our container, the problem is
	// what type does the method return, or use for its running total?
	size_type get_total_item_size() const {
		typename item_set::iterator i = items.begin ();
		size_type total = i->size ();
		for (++i; i != items.end (); ++i)
		{
			total += i->size ();
		}
		return total;
	}
	
	void add() {
		T item;
		items.insert (item);
	}

	private:
		template<typename F>
		struct LessT {
			bool operator()(const F &lhs, const F &rhs) const {
				return lhs.size () < rhs.size ();
			}
		};
		
		// Let's say container orders only by the size of it's items
		// such that items are sorted from shortest item to longest item
		typedef typename std::set<T, LessT<T> > item_set;
		item_set items;
};

int main () {
	container<weird_thing> foo;
	
	// Add 5 weird_things to foo
	foo.add ();
	foo.add ();
	foo.add ();
	foo.add ();
	foo.add ();
	
	// This should be 3, but gives 1.
	std::cout << foo.get_total_item_size () << std::endl;
	
	return 0;
}

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Lexical Unit posted:

Contrived example ahoy!

In that example, you'd want to use T::size_type. For merely counting the number of elements, (like .size() in STL containers), you'd use size_t. It's just a question of what exactly you want to measure.

EDIT: if you need both, you could have size_type and contained_size_type typedefs.

That Turkey Story
Mar 30, 2003

Lexical Unit posted:

Contrived example ahoy!

That's entirely a different issue -- your problem there is that you're misusing the size type for something other than its actual purpose. The size type is the unsigned counter-part of the container's iterator difference type and is used for things like the number of elements in the container, unrelated to that "weird_thing" size_type in your example.

As for your original question, again, just use the unsigned counterpart of your iterator difference type. Usually these are std::ptrdiff_t and std::size_t respectively, but they might be different depending on your container's needs.

cronio
Feb 15, 2002
Drifter

Neslepaks posted:

Don't do these casts when writing C. void pointers are always implicitly castable to other pointers, all you'll achieve is to hide warnings you'd want to see (like if you forgot to include the prototype for malloc, or there's a more serious type mismatch).

Not having the cast there is a compile error in C++ -- is that not true in C?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

cronio posted:

Not having the cast there is a compile error in C++ -- is that not true in C?

This is one of the important differences between C and C++. In C, void* can automatically be converted to any pointer type.

Lexical Unit
Sep 16, 2003

Ah I see. These standard container typedefs have a me a bit confused because they seem a little inconsistent from my perspective. It seems like value_type, pointer, const_pointer, reference, and const_reference, are all directly related to the type of the items in a container whereas size_type oddly has nothing at all to do with the type of the items in a container, but rather apparently only the number said items in the container. I always get hung up on these little details that people seem to think are obvious... :downs:

Adbot
ADBOT LOVES YOU

WalletBeef
Jun 11, 2005

What is the best, free, windows C++ compiler?

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