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
TSDK
Nov 24, 2003

I got a wooden uploading this one

DoctorTristan posted:

code:
template< class TParam, class TPhiFunc >
    void EA2ParameterAndSkeletonArray< TParam, TPhiFunc >::addParameter ( const TParam& param )
    {       
        ( * ( parameterStore.begin() ) )->push_back (
            ParamPointerPair ( param,  new EA2Skeleton(numSkeletonSegments) ) );
        }
code:
template <class TParam>
struct ParamAndPointerToSkel {
    TParam parameter;
    EA2Skeleton* pToSkel;
    ParamAndPointerToSkel() : pToSkel(0) {}
    ParamAndPointerToSkel ( TParam inpParam, int numSegments ) : 
     parameter ( inpParam ) {pToSkel = new EA2Skeleton ( numSegments );}
    ParamAndPointerToSkel ( TParam inpParam, EA2Skeleton* inpPskel) :
     parameter ( inpParam ) , pToSkel ( inpPskel ) {}
    ~ParamAndPointerToSkel() {delete pToSkel;}
    };
Here's your problem.

You're creating a temporary ParamPointerPair object, pointing to the new EA2Skeleton object, and then pushing a copy of that object into the list. So you now have at least two objects of type ParamPointerPair pointing to the same skeleton.

As that temporary object goes out of scope, the destructor deletes the instance of EA2Skeleton, returning the memory to the free memory pool, ready to be allocated on the next addParam.

EDIT: One more thing - typedef's are supposed to be there to make your code more concise and readable, not to give really long, unhelpful names to things.

TSDK fucked around with this message at 18:26 on Jun 22, 2009

Adbot
ADBOT LOVES YOU

DoctorTristan
Mar 11, 2006

I would look up into your lifeless eyes and wave, like this. Can you and your associates arrange that for me, Mr. Morden?
Thanks for spotting that. I'm pretty sure my C++ book warned about that very thing, but the lesson didn't sink in I guess.

So I guess the simplest solution would be to have the container class clean up the heap memory on destruction, rather than ParamPointerPair? (once I'm done with the ParamPointerPair objects I'm done with the container)

Will write better typedefs next time, promise.

TSDK
Nov 24, 2003

I got a wooden uploading this one

DoctorTristan posted:

So I guess the simplest solution would be to have the container class clean up the heap memory on destruction, rather than ParamPointerPair? (once I'm done with the ParamPointerPair objects I'm done with the container)
Yes. A good rule of thumb is to deallocate memory (or delete objects) in the same place that they're allocated/created. So if you new something in EA2ParameterAndSkeletonArray, then you should delete it there too.

Your current code breaks that rule of thumb by creating objects in one place (EA2ParameterAndSkeletonArray) and deleting them in another (ParamAndPointerToSkel) and that's exactly what has caused problems.

Note that you could also logically fix the problem by moving the new totally over into ParamAndPointerToSkel and give the class full deep-copy semantics with implementations of a copy constructor and assignment constructor (again restoring the above rule of thumb). But this wouldn't be very optimal, so the first fix is preferable.

TSDK fucked around with this message at 22:30 on Jun 22, 2009

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum
I have a really cryptic question.

I have a plugin for a source dedicated server (for counter strike source specifically) and I am trying to do an auto update feature for the plugin. Now, I can identify the version I have and the latest version, that was easy. The problem is downloading the new file. I got curl and am using it correctly, I have a separate test project that just downloads the file. The problem is, whenever I try and use the function within the server plugin, I get error # 27, which is "A memory allocation request failed. This is serious badness and things are severely screwed up if this ever occurs".
Sweet! Love that error, anyone have an ideas on wtf?

edit: you probably need the code lol, it's just a curl example ripped right from the website so I knew it worked.
code:
struct FtpFile {
	const char *filename;
	FILE *stream;
};

static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
	struct FtpFile *out=(struct FtpFile *)stream;
	if(out && !out->stream) {
		/* open file for writing */
		out->stream=fopen(out->filename, "wb");
		if(!out->stream)
			return -1; /* failure, can't open file to write */
	}
	return fwrite(buffer, size, nmemb, out->stream);
}


int download(std::string filename)
{
	CURL *curl;
	CURLcode res;
	struct FtpFile ftpfile={
		filename.c_str(), /* name to store the file as if succesful */
		NULL
	};

	curl_global_init(CURL_GLOBAL_DEFAULT);

	curl = curl_easy_init();
	if(curl) {
		/*
		* Get curl 7.9.2 from sunet.se's FTP site. curl 7.9.2 is most likely not
		* present there by the time you read this, so you'd better replace the
		* URL with one that works!
		*/
		curl_easy_setopt(curl, CURLOPT_URL,
			"http://plugin.zomblerz.com/ld_plugin_0001.dll");
		/* Define our callback to get called when there's data to be written */
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
		/* Set a pointer to our struct to pass to the callback */
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);

		res = curl_easy_perform(curl);

		/* always cleanup */
		curl_easy_cleanup(curl);

		if(CURLE_OK != res) {
			/* we failed */
			Msg("curl told us %d\n", res);
		}
	}

	if(ftpfile.stream)
		fclose(ftpfile.stream); /* close the local file */

	curl_global_cleanup();

	return 0;
}
and it doesn't work in the dll :\

Sweeper fucked around with this message at 03:36 on Jun 23, 2009

Standish
May 21, 2001

code:
return fwrite(buffer, size, nmemb, out->stream);
Your CURLOPT_WRITEFUNCTION callback is supposed to return the number of bytes written. fwrite() returns the number of items written.

Also move the fopen() out of the callback so you can do proper error checking, it's possible that returning -1 from CURLOPT_WRITEFUNCTION is confusing it.

Standish fucked around with this message at 12:38 on Jun 23, 2009

Rampager
Sep 15, 2007

:roboluv:allow me to buy
you a drink, miss
:roboluv:
Currently I have this code that executes and stalls until a character is entered and then 2 seconds from that moment a handler will be triggered. However what I'm aiming for is the ability to interrupt getchar() or fgets() [things like loops are interrupted fine] and fire off the handler after the 2 seconds the signal was called.


code:
#include <sys/time.h> and <string.h>


int main(int argc, char *argv[]) {
   // Set CPU timer
   signal(SIGVTALRM, handler);
   struct itimerval itval;
   itval.it_value.tv_sec = 2;
   itval.it_value.tv_usec = 0;
   itval.it_interval.tv_sec = 0;
   itval.it_interval.tv_usec = 0;
   setitimer(ITIMER_VIRTUAL, &itval, NULL);
 
   //call functions and other code goes in here

   return(0);
}

// handler - handle SIGVTALRM
void handler(int sig) {
   printf("Time's up!\n");
   
   exit(0);
}
I am probably going about this the wrong way because I'm pretty inexperienced (3 months?) with coding in general and basically dabbled into timers about a day ago.

Any help is much appreciated, if what I'm aiming for is impossible then that's cool too :). Thanks in advance!

Rampager fucked around with this message at 17:00 on Jun 23, 2009

Standish
May 21, 2001

ITIMER_VIRTUAL only increments while the process is actually running, not while it's blocked on io, try ITIMER_REAL instead.

Also printf() isn't safe to call inside a signal handler (and neither are most library functions in general, see man(7) signal).

Rampager
Sep 15, 2007

:roboluv:allow me to buy
you a drink, miss
:roboluv:
This works well, thanks!

I'll have to check out signal more indepth now.

Lexical Unit
Sep 16, 2003

I don't seem to understand something fundamental about boost::call_traits.
code:
#include <boost/call_traits.hpp>

template<class T>
void foo(typename boost::call_traits<T>::param_type) { }

int main()
{
	int i = 5;
	foo (i);
	foo (5);
}
error: no matching function for call to 'foo(int&)' — foo (i)
error: no matching function for call to 'foo(int)' — foo (5)


Why shouldn't this work?

Avenging Dentist
Oct 1, 2005

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

Lexical Unit posted:

Why shouldn't this work?

How would the compiler deduce the type of T? (It wouldn't.)

Lexical Unit
Sep 16, 2003

I kept looking at example 4 without getting it. :doh:

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum

Standish posted:

code:
return fwrite(buffer, size, nmemb, out->stream);
Your CURLOPT_WRITEFUNCTION callback is supposed to return the number of bytes written. fwrite() returns the number of items written.

Also move the fopen() out of the callback so you can do proper error checking, it's possible that returning -1 from CURLOPT_WRITEFUNCTION is confusing it.
Thank you! I have narrowed it down to not being able to open the file correctly, anyone know what's up with that?

edit: So it opens the file now, but I still get error #27

here is the code, again it works in it's own program, but not in the loaded .dll, did I do the return incorrectly for the writefunction?

code:
struct DownloadableFile {
	const char *filename;
	FILE *stream;
};

// Writes the download to disk
int libcurlFileWriter(void *buffer, size_t size, size_t nmemb, void *stream)
{
	struct DownloadableFile *out=(struct DownloadableFile *)stream;
	fwrite( buffer, size, nmemb, out->stream );
	return (size*nmemb);
}


int download(std::string filename, std::string updateDownloadURL)
{
	struct DownloadableFile fileDownloading={
		filename.c_str(),
		NULL
	};

	fileDownloading.stream = fopen(fileDownloading.filename, "wb+");

	if (!fileDownloading.stream) 
	{
		Msg("File not opened.");
		return -1;
	}

	CURL *curl=NULL;
	CURLcode result;
	std::string buffer="";
	char errorBuffer[CURL_ERROR_SIZE];

	curl=curl_easy_init();
	if ( curl )
	{
		curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
		curl_easy_setopt(curl, CURLOPT_URL, updateDownloadURL.c_str());

		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, libcurlFileWriter);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fileDownloading);

		result=curl_easy_perform( curl );

		curl_easy_cleanup( curl );

		if ( result == CURLE_OK )  
		{ 
			Msg("File downloaded successfully!");
			return 1;
		}
		else 
		{
			Msg("Error [%d] - %s", result, errorBuffer);
			return -1;
		}
	}

	return 0;
}
Edit 2: New info! If I set the debug stream to a file, it prints nothing in the file. No attempting to connect, nothing.
Usually if it's successful it does one of these:
code:
* About to connect() to plugin.zomblerz.com port 80
*   Trying 208.113.150.169... * connected
* Connected to plugin.zomblerz.com (208.113.150.169) port 80
> GET /ld_plugin_0001.dll HTTP/1.1
Host: plugin.zomblerz.com
Accept: */*

< HTTP/1.1 200 OK
< Date: Tue, 23 Jun 2009 23:01:42 GMT
< Server: Apache/2.0.63 (Unix) PHP/4.4.7 mod_ssl/2.0.63 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
< Last-Modified: Mon, 22 Jun 2009 01:10:12 GMT
< ETag: "4906d9a-77600-89336500"
< Accept-Ranges: bytes
< Content-Length: 488960
< Content-Type: application/x-msdownload
* Connection #0 to host plugin.zomblerz.com left intact
* Closing connection #0
With mine it does none of that meaning it fails early on I guess...

Sweeper fucked around with this message at 00:03 on Jun 24, 2009

Adahn the nameless
Jul 12, 2006
I'm trying to write a program that reads an ASCII file and writes the same data to a binary file. Every time I run the program I'm getting a segmentation error, which I understand occurs when a pointer goes out of scope. Thing is, I can't figure out why this is happening. Here's the relevant bit of code:

code:
 

	//Read source data to temp variale and write that data to destination
	
               int temp;

               while (!source.eof()) {
		source >> temp;
		destination.write(reinterpret_cast<char*>(temp), sizeof(temp));
	       }

Source is the file I am reading from, and destination is the file I'm writing to.

I guess I could change the int temp to an character array and read all of my source file to that, then write everything to the binary file, but I am really curious to know why this doesn't work.

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

Adahn the nameless posted:

I'm trying to write a program that reads an ASCII file and writes the same data to a binary file. Every time I run the program I'm getting a segmentation error, which I understand occurs when a pointer goes out of scope.
That's not at all what a segfault is.

What is source? What is designation? Are they opened correctly? Are you doing proper error checking when you open the streams/file descriptors? Have you run this through a debugger to pinpoint the line where it's crashing?

edit: ah, didn't catch the missing addressof operator.

Dijkstracula fucked around with this message at 21:51 on Jun 24, 2009

Avenging Dentist
Oct 1, 2005

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

Adahn the nameless posted:

I guess I could change the int temp to an character array and read all of my source file to that, then write everything to the binary file, but I am really curious to know why this doesn't work.

You are trying to turn a number (e.g. 10) into a pointer. Dereferencing the memory address 0x0000 000A (10) is almost certainly going to fail. You want to reinterpret_cast<char*>(&temp).

All that is assuming that you want to do the following (which I doubt):
code:
// input (assumes little endian):
1953789250

// output:
Butt
(Note: 1953789250 = 66*2560 + 117*2561 + 116*2562 + 116*2563)

Avenging Dentist fucked around with this message at 21:52 on Jun 24, 2009

Fecotourist
Nov 1, 2008

Avenging Dentist posted:

Yes, through non-standard extensions supported in gcc and MSVC (stolen verbatim from one of my projects):

code:
struct vec2d
{
	union
	{
		struct
		{
			float x;
			float y;
		};
		float coord[2];
	};
};

Sorry to dredge this up from April (pg 95), but if you're returning these things by value, g++ at least stumbles when it's optimization time (either -O2 or -O3). I have some simple expression template code which lets the user build a pipeline of the form Op1<Op2<Op3> > > and applies it over a huge set of 4-float objects. Without the union trick it runs just as fast as handwritten inline code (all functions are inline, so there's no overhead return-by-value after optimization), but with it there's a repeatable 15% slowdown for my current test case and even simplified variations of it. I'm not even using the array part of the union. The speed difference is between states of this #if:
code:
#if 1
    union {
        struct { float A, B, C, D; };
        float X[4];
    };
#else
    float A, B, C, D;
#endif
I assume the difficulty is in keeping values in registers when the source code specifies the alternate array view of the same data. Even though the compiler should have all the information and assurances it should need in order to end up with the same optimized code, right?
It turns out that, at the moment at least, indexed access to components is by indices known at compile time, so specialized get<int>(void) member functions seems to get the best of both worlds. But what I really want is the best of all 3 worlds. Is there some obscure syntax that might help?

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum
Woohoo new errors! Now when I try and set the url it gives me back error 27, but when I do the perform it's error #3! The original problem was caused by using a bad libray... lame. So I got a new one, and this one is now being lame.

code:
// Definition of a file download
struct DownloadableFile {
	const char *filename;
	FILE *stream;
};

// Writes the download to disk
int libcurlFileWriter(void *buffer, size_t size, size_t nmemb, void *stream)
{
	struct DownloadableFile *out=(struct DownloadableFile *)stream;
	fwrite(buffer, size, nmemb, out->stream);
	return (size*nmemb);
}


int download(std::string filename, std::string updateDownloadURL)
{
	struct DownloadableFile fileDownloading={
		filename.c_str(),
		NULL
	};

	Msg("url = %s, filename = %s\n", updateDownloadURL.c_str(), filename.c_str());

	fileDownloading.stream = fopen(fileDownloading.filename, "wb");

	if (!fileDownloading.stream) 
	{
		Msg("File not opened.\n");
		return -1;
	}

	CURL *curl=NULL;
	CURLcode result;
	const char *url = updateDownloadURL.c_str();
	char errorBuffer[CURL_ERROR_SIZE];

	curl=curl_easy_init();
	if ( curl )
	{
		FILE *debugFile;
		debugFile = fopen("test.txt", "wb");

		curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
		result = curl_easy_setopt(curl, CURLOPT_URL, url);
		Msg("Error [%d] - %s\n", result, curl_easy_strerror(result));
		Msg("url = %s\n", url);
		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
		curl_easy_setopt(curl, CURLOPT_HEADER, 0);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, libcurlFileWriter);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fileDownloading);
		curl_easy_setopt(curl, CURLOPT_STDERR, debugFile);

		result=curl_easy_perform( curl );

		curl_easy_cleanup(curl);

		if ( result == CURLE_OK )  
		{ 
			Msg("File downloaded successfully!\n");
			return 1;
		}
		else 
		{
			Msg("Error [%d] - %s\n", result, curl_easy_strerror(result));
			return -1;
		}
	}

	return 0;
}
This:
result = curl_easy_setopt(curl, CURLOPT_URL, *url);
Msg("Error [%d] - %s\n", result, curl_easy_strerror(result));
prints out error 27, Out of Memory.

This:
result=curl_easy_perform(curl);
Msg("Error [%d] - %s\n", result, curl_easy_strerror(result));
prints out Error 3, malformed URL.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
First, try to reduce your code to a minimal test case that shows the failure, preferably as a complete program. Otherwise, people can't really compile or test your code so unless you did something really obviously wrong, you won't get any help.

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum
quote != edit

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Here's a cool feature in C++0x that I wasn't aware of, and am not actually 100% sure how to use it yet: axioms. It looks like they're used to help the compiler make optimizations and could very well make expression templates obsolete as algebraic optimizers.

From the C++0x draft standard:

code:
concept Semigroup<typename Op, typename T> : CopyConstructible<T> {
    T operator()(Op, T, T);
    axiom Associativity(Op op, T x, T y, T z) {
        op(x, op(y, z)) == op(op(x, y), z);
    }
}

concept Monoid<typename Op, typename T> : Semigroup<Op, T> {
    T identity_element(Op);
    axiom Identity(Op op, T x) {
        op(x, identity_element(op)) == x;
        op(identity_element(op), x) == x;
    }
}

Adahn the nameless
Jul 12, 2006

Avenging Dentist posted:

You are trying to turn a number (e.g. 10) into a pointer. Dereferencing the memory address 0x0000 000A (10) is almost certainly going to fail. You want to reinterpret_cast<char*>(&temp).

All that is assuming that you want to do the following (which I doubt):
code:
// input (assumes little endian):
1953789250

// output:
Butt
(Note: 1953789250 = 66*2560 + 117*2561 + 116*2562 + 116*2563)

That did it, thanks. I have the program working in a sort of way.

I don't really get your joke though. Cause I'm dumb. What I did was read from a list of numbers and write those same numbers to a binary file.

Fecotourist
Nov 1, 2008

Avenging Dentist posted:

Here's a cool feature in C++0x that I wasn't aware of, and am not actually 100% sure how to use it yet: axioms. It looks like they're used to help the compiler make optimizations and could very well make expression templates obsolete as algebraic optimizers.

Causal assert()? I'm all for ways to tell the compiler about invariants that it can assume to be true when it's optimizing. For example, "if condition A is true, then cheap computation B is equivalent to expensive C". If the compiler is instantiating a template and can deduce that A is always true in this context, that could be a big win.
This is probably just daydreaming but I can imagine implementing something like interval arithmetic, where you make guarantees about the range of a numerical function's output, and the compiler is prodded to pick the most efficient approximation that's accurate enough. Like in y=exp(sin(x)), you know that the argument of exp() is between -1 and 1, so maybe use a cheap approximation.

Avenging Dentist
Oct 1, 2005

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

Fecotourist posted:

Causal assert()?

It's the opposite of an assert, basically. It says to the compiler, "don't bother checking this, it's always true". Hence the name "axiom".

Fecotourist
Nov 1, 2008

Avenging Dentist posted:

It's the opposite of an assert, basically. It says to the compiler, "don't bother checking this, it's always true". Hence the name "axiom".

"Opposite" only in the sense that it happens before, rather than after. More precisely "assert(), but causal". Either way, you're making a claim that something is true, the only difference is whether the compiler verifies its truth after the computation or does the computation with that knowledge in mind up front.
If you as a programmer make a mistake and assert() something that isn't always true, the mode of failure is unexpected core dumps, usually an easy investigation. If you claim as an axiom something that isn't always true (like "F commutes with G" when it actually doesn't), have fun tracking that bug down.
Anyway, what I get out of expression templates is the elimination of temporaries and unnecessary memory traffic, and I can't see that axiom obsoletes them in that sense.

Lexical Unit
Sep 16, 2003

I thought axioms were the method of creating concepts? Just as you've shown, they allowed you to formalize, in code, the self-documenting concepts of Semigroup and Monoid.

Or is there another way you'd write new (or simply not standard/compiler provided) concepts in C++0x?

Avenging Dentist
Oct 1, 2005

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

Fecotourist posted:

Anyway, what I get out of expression templates is the elimination of temporaries and unnecessary memory traffic, and I can't see that axiom obsoletes them in that sense.

Using expression templates for elimination of temporaries has already been rendered unnecessary without concepts, thanks to rvalue references.

Lexical Unit posted:

Or is there another way you'd write new (or simply not standard/compiler provided) concepts in C++0x?

For most concepts, you just write out the associated functions. Axioms are meant to build on that.

Fecotourist
Nov 1, 2008

Avenging Dentist posted:

Using expression templates for elimination of temporaries has already been rendered unnecessary without concepts, thanks to rvalue references.

I understand how rvalue references can eliminate some copies by enabling move constructors, but does it really allow loop fusion between separate calls to operators?
For example, A B and C are array-like objects in y=(A+B)*C. If you define the math operators without expression templates, the compiler does A+B in one pass to fill a temporary, then another pass to multiply the temporary with C to fill y. Do rvalue references let the compiler see through the logic and do it all at once?
Ok, you can have the operators all return lazy-evaluated ranges, operator= is the only one to actually iterate through elements, but you can do all that right now.

Avenging Dentist
Oct 1, 2005

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

Fecotourist posted:

I understand how rvalue references can eliminate some copies by enabling move constructors, but does it really allow loop fusion between separate calls to operators?

You are conflating two separate topics. I was specifically referring to elimination of temporaries using expression templates. Expression templates could potentially be smarter, but rvalue references eliminate temporaries except when both of the operands in your expression tree are leaves (assuming you don't std::move one or more of the leaves).

In your example, the end result would be one temporary that gets moved into y. You could have multiple temporaries, which I suppose would benefit from expression templates, or you could just rely on your compiler being sufficiently smart as to take advantage of axioms to clean up the expression tree.

Now if only there was an axiom that would allow operator && to short-circuit...

Avenging Dentist fucked around with this message at 18:34 on Jun 25, 2009

Fecotourist
Nov 1, 2008

Avenging Dentist posted:

In your example, the end result would be one temporary that gets moved into y. You could have multiple temporaries, which I suppose would benefit from expression templates, or you could just rely on your compiler being sufficiently smart as to take advantage of axioms to clean up the expression tree.

My point was that even with a single moved temporary, there's an extraneous loop that I don't see axiom/concept/rvalue-references helping to eliminate. There's one big loop that creates t=(A+B), and another big loop to do t*=C, then the (trivial, one pointer assignment) move constructor y=t, right? If I need those loops fused (which is 90% of what I need from ET), then I pretty much need to do everything under C++0x that I need to do now.

Avenging Dentist
Oct 1, 2005

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

Fecotourist posted:

My point was that even with a single moved temporary, there's an extraneous loop that I don't see axiom/concept/rvalue-references helping to eliminate.

Yes, and I wasn't talking about loop fusion at all. I was simply talking about temporaries.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Paging That Turkey Story to the C++ thread...

Is the following legal in C++0x? The gcc-snapshot package rejects it, but gcc 4.4's initializer list implementation is buggy as gently caress.

code:
int *i = new int[4]{1, 2, 3, 4};
The spec would seem to agree with me:
pre:
new-expression:
    ::opt new new-placementopt new-type-id new-initializeropt
    ::opt new new-placementopt ( type-id ) new-initializeropt
new-placement:
    ( expression-list )
new-type-id:
    type-specifier-seq new-declaratoropt
new-declarator:
    ptr-operator new-declaratoropt
    noptr-new-declarator
noptr-new-declarator:
    [ expression ]
    noptr-new-declarator [ constant-expression ]
new-initializer:
    ( expression-listopt )
    braced-init-list

...

15 A new-expression that creates an object of type T initializes that object as follows:
   — If the new-initializer is omitted, the object is default-initialized (8.5); if no initialization is performed,
     the object has inteterminate value.
   — Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct-initialization.
I've underlined the relevant bits.

That Turkey Story
Mar 30, 2003

I think you're correct but I'm probably just as unfamiliar with this area of standardization as you are. I'm almost positive that one of the use-cases for new with initializers was for array types, but I may be wrong on that. The standard certainly seems to make it sound like it is allowed. Does new with initializer lists work with structs in 4.4?

Avenging Dentist
Oct 1, 2005

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

That Turkey Story posted:

Does new with initializer lists work with structs in 4.4?

Only if you have a constructor that takes an std::initializer_list<T>. The grammar seems to suggest that new int{4} and new int[3]{1, 2, 3} are both legit, and nothing in 5.3.4 (New) or 8.5 (Initializers) suggests that either are invalid. The 2003 standard certainly invalidates them both, though (for different reasons).

I ask because I'm giving a talk to my department on C++0x tomorrow and I just realized today that my example doesn't compile in 4.4.

EDIT: lol I managed to make it crash with an internal compiler error by trying std::string{"foo"};

Guess I'll compile 4.4 or the nightly or whatever tomorrow and start submitting bug reports.

Avenging Dentist fucked around with this message at 06:23 on Jun 26, 2009

Sabotaged
Jul 6, 2004

What could cause a call to close() to block (seemingly) indefinitely? The file descriptor was created with pipe().

csammis
Aug 26, 2003

Mental Institution
This might be a crazy idea, but here goes.

I've got a VS 2008 solution with fourteen or so C++ projects in it, all of which get statically linked together into a single executable. Each of the fourteen projects has a string table. The VS string table editor is not aware of other projects in the solution and will happily let you create duplicate IDs that are only found when the resources are compiled together (the final .exe project includes the other projects' resources into its own). This late-notice collision is not cool, and our resource IDs are fragmented enough that it happens pretty much every time one of the developers adds a new string to any project.

One of my teammates and I got to talking today, and we wondered if there is a sane way to generate string ID numbers at compile time rather than design time; that is, convince the resource compiler - or some prebuild process - to collate the existing string tables and reassign non-colliding IDs once all the strings are known. This would result in string IDs [potentially] changing in each endstate image, but that shouldn't be a problem...right?

There are probably dozens of reasons that make this a terrible idea. For one thing, the VS string table editor wouldn't know what the gently caress, which probably will make localization difficult - I don't know the exact localization process that our company uses, only that we contract out to have it done. What I'm looking for is:

a) reasons this is stupid so I can focus my unused energy somewhere more useful
b) ways this might work at all, just so I can play around with it

It probably won't end up being valuable to anyone, but I think it's an interesting thought exercise and I'm sort of underscheduled this month :v:

baquerd
Jul 2, 2007

by FactsAreUseless
I don't know poo poo about Visual Studio, but why not just make an internal registration database keyed to the IDs that each developer drops their IDs into. Hell, you could even just do it as a wiki page.

csammis
Aug 26, 2003

Mental Institution

quadreb posted:

I don't know poo poo about Visual Studio, but why not just make an internal registration database keyed to the IDs that each developer drops their IDs into. Hell, you could even just do it as a wiki page.

I'm really not sure what you're suggesting with this...

baquerd
Jul 2, 2007

by FactsAreUseless
I'm suggesting a process to self-regulate the assignment of new ID numbers.

csammis
Aug 26, 2003

Mental Institution

quadreb posted:

I'm suggesting a process to self-regulate the assignment of new ID numbers.

VS already autoassigns the IDs numbers, which is the problem because it does so stupidly :) I'm looking for a new process to autoassign at a different point in the cycle.


e: Even if the string table designer did understand multiple projects in a solution and could autogenerate IDs that don't conflict within a single solution, that doesn't help when multiple instances of VS (many developers) are generating the same IDs.


e2: I should mention that resource IDs are two-byte unsigned integers.

csammis fucked around with this message at 14:24 on Jun 30, 2009

Adbot
ADBOT LOVES YOU

Avenging Dentist
Oct 1, 2005

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

csammis posted:

VS already autoassigns the IDs numbers, which is the problem because it does so stupidly :) I'm looking for a new process to autoassign at a different point in the cycle.

Manually fix the IDs once, never worry about it again (for a while anyway)? If it's anything like resource IDs, it's sequential. For example:

code:
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        108
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1026
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

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