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
digibawb
Dec 15, 2004
got moo?

aViR posted:

That approach should work, and yes you would cast the pointers to unsigned integers, do your math, and cast back, e.g. (untested):
code:
newStruct.strings[i] = (char*)((unsigned int)oldStruct.strings[i] - (unsigned int)oldstruct.hugeCharArray + (unsigned int)newStruct.hugeCharArray);
note: this assumes that int is the same size as char* on your architecture.

There's no need for any of those casts.

Adbot
ADBOT LOVES YOU

digibawb
Dec 15, 2004
got moo?

Ledneh posted:

That reminds me. For some reason, as soon as I started my sun studio 12 project it allowed me to do just that: put template class declarations in a .hpp and their implementations in a .cpp that includes the .cpp, just like a normal class. And it worked fine. It was only later that I remembered that this has never worked for me before and I still haven't found out what I did to the project settings to make it go :psyduck:

Ok, I've re-written this post several times now, and I think I've got the stupid stuff straight in my head. What I was finding in my test case was just the effects of the stuff I linked below.

If you have implemented the template in a cpp file, and *used* it in that same cpp, then for all the combinations of templates parameters that you have used, it will be available to the rest of the code. If you try and use it for a combination not used in that cpp file, you will get unresolved externals. You could however, implment it in another cpp file with those other template paramters and everything would work fine for them, and you could have totally different implementations, I assume this just comes from template specialisation.

Now, what's slightly more odd, and I'm less clear on, was that Visual Studio lets you implement the template multiple times, using the same template paramters, and it wont give linker issues about multiply defined symbols, though it only seems to use one of the implementations. EDIT: duh, this is the normal usage case, except normally they would all be defined with the same code.

EDIT: Jesus, I'm just getting more and more convinced that VS is just doing weird and crazy stuff. You will only be able to use the functions you have actually called, as otherwise it won't have actually compiled them into the translation unit. So, if you really want to use this crazy way of making templates, use explicit instantiation, doing it any other way seems like a lesson in pain.

In conclusion, I'm pretty sure what I originally typed was correct, you should only be able to use templates if they have been defined in the same translation unit, unless you use explicit template instantiation.



Explicit Template Instantiation:
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=/com.ibm.vacpp7l.doc/language/ref/clrc16explicit_instantiation.htm

digibawb fucked around with this message at 00:10 on Dec 10, 2008

digibawb
Dec 15, 2004
got moo?

Subotai posted:

I came across this in some code today and wondered if it actually does anything?

code:
void func(SomeStruct *pInst)
{

   unsigned char *pBuff;

   pBuff = (unsigned char *)pInst;
   pInst = (SomeStruct *) pBuff;

   // Other stuff, both pointers are used
}
Is there any reason to cast the data to a unsigned char and back? Does this do anything with the way the compiler handles the data?

It should make no difference at all.

digibawb
Dec 15, 2004
got moo?

Avenging Dentist posted:

The second cast is superfluous, but the first one allows addressing at the byte level for the struct.

He asked whether there was any point in casting back and forth, I was just answering that question ;)

Avenging Dentist posted:

MSVC defers member function instantiation of template classes until they are referenced. I don't know if it actually violates the standard, except in that it won't diagnose errors of non-referenced methods, but eh.

I'm not sure if it breaks standard compliance either, but I actually like the "feature". It can be handy for having things where the code for a specific function will only work for a certainly type, or class of type, say a pointer, but you will only use that function for that type/class of type. Having said that, I have to deal with 4-5 different compilers at work, so don't get to make use of it, but eh, whatever.

digibawb fucked around with this message at 00:42 on Dec 10, 2008

digibawb
Dec 15, 2004
got moo?

Avenging Dentist posted:

Well, here's a good reason why not to do this: segfaults

http://codepad.org/wistRvN1

I'm not actually sure why this segfaults. :confused:

EDIT: The more I think about it, the more it makes sense, given that you wouldn't necessarily know how many destructors to call. Still, this makes C++ slightly more stupid than before, since you can't dynamically allocate an array of objects unless they're default constructible.

code:
#include <iostream>

using namespace std;

class Object {
public:
	Object( int param ) : param( param ) {
		cout << "in " << param << endl;
	}

	~Object( void ) {
		cout << "out " << param << endl;
	}

private:
	int param;
};

template< typename T >
T* AllocateObjectArray( size_t count, int param ) {
	char* buffer = ( char* )malloc( sizeof( size_t ) + ( sizeof( T ) * count ) );

	*( size_t* )buffer = count;

	char* baseBuffer = buffer + sizeof( size_t );
	char* p = baseBuffer;
	for ( size_t i = 0; i < count; i++, p += sizeof( T ) ) {
		new( p ) T( param );
	}

	return reinterpret_cast< T* >( baseBuffer );
}

template< typename T >
void FreeObjectArray( T* ptr ) {
	if ( ptr == NULL ) {
		return;
	}

	char* buffer = reinterpret_cast< char* >( ptr ) - sizeof( size_t );

	size_t count = *( size_t* )buffer;
	for ( size_t i = 0; i < count; i++ ) {
		ptr[ i ].~T();
	}

	free( buffer );
}


int main( int argc, char* argv[] ) {
	Object* objects = AllocateObjectArray< Object >( 2, 4 );
	FreeObjectArray( objects );

	system( "pause" );

	return 0;
}
How about something like that?

EDIT: Obviously the parameter passing could be handled better, likely with some boost trickery, but you get the idea.

digibawb fucked around with this message at 23:29 on Dec 11, 2008

digibawb
Dec 15, 2004
got moo?

Avenging Dentist posted:

The semantics of new/delete are among my least favorite parts of C++, and except for placement new (which has awful syntax in my opinion)

Agreed.

I re-wrote all of our memory allocation handling earlier on this year so we could use a custom allocator for everything, and it was a lesson in pain. Not helping matters were that MFC has a nice bug where they new stuff in one place and call free on it later. wxWidgets wasn't a huge deal better, they have a nice part in their style guide which says to not do any allocation during static init, so that people can use custom allocators easily, then they go ahead and just break that rule left, right and centre. *shakes fist*

EDIT: Oh, and the new call in MFC is in a header, so you pick up that call yourself, but the free is in the dll... grrr

digibawb
Dec 15, 2004
got moo?

hexadecimal posted:

code:
.. snip
This generates segmentation fault for lines f->a() and f->bar() which is a run time error. This is what i was trying to say. What is wrong about it?

Perhaps I misread or misunderstood the person who asked about this.

vvvvvvvvvvvvvvvv ok, admittedly I am not an expert on how virtual functions are implemented in C++. Thank you for your explanation, and sorry for giving the wrong one to the original person asking about this.

If you didn't dereference this in bar, then on many compilers, you would get away with doing the call with no harm done. However, it's obviously not good practice, as it's compiler specific, but most compilers (read: the 4-5 that I use anyway)behave the same way for this case.

digibawb
Dec 15, 2004
got moo?

Staggy posted:

Alternatively you could use a Switch-Case.
code:
switch (n){
   case 0:
    cin >> value1;
    break;
   case 1:
    cin >> value2;
    break;
}

Yes, let's teach people the for-case paradigm.



You'd be better off writing a function which deals with printing the statement, and fetching the input, then calling it 5 times, either via a loop and an array of ints, or just by calling it 5 times explicitly.

EDIT: or, since it's a relatively small amount of logic, just shoving it inline with the array

digibawb fucked around with this message at 20:57 on Jan 11, 2009

digibawb
Dec 15, 2004
got moo?

honeymustard posted:

Tell me more? Our programming lecturer guy seems to encourage switch-cases.

There's nothing wrong with switch-case, it's awesome.

Doing it inside a loop based on the iterator is just silly however (in general anyway). With a small case like this it might not look all that crazy, but once you go down the road, you get to places like http://thedailywtf.com/Articles/The_FOR-CASE_paradigm.aspx

digibawb
Dec 15, 2004
got moo?

schnarf posted:

I'm betting the union isn't 4 bytes as you'd expect.

How much you willing to bet?

It will be the vtable, as has already been covered.

digibawb
Dec 15, 2004
got moo?
Use a const_iterator for the const object.

digibawb
Dec 15, 2004
got moo?
You can declare it inline in the implementation file as long as that is the only place you use it, as it won't be visible to the linker.

digibawb
Dec 15, 2004
got moo?
I have used Memory Validator ( http://softwareverify.com/cpp/memory/index.html ) many times with great success. It isn't free, but there's a 30 day trial iirc. The interface is rather clunky, but if you can get past that, it has a lot of good features.

digibawb
Dec 15, 2004
got moo?
fprintf writes to a file, you haven't given it a file to write to

(though I suspect you wanted printf, not fprintf)

digibawb fucked around with this message at 20:18 on Oct 27, 2009

digibawb
Dec 15, 2004
got moo?

Red Alert posted:

can't you use sizeof?

On what exactly?

digibawb
Dec 15, 2004
got moo?

Lexical Unit posted:

I have never programmed in Windows before and Visual Studio is making me feel dumb.

I need to link to an external library right, so I added the path the library to "Additional Library Directories." And then added the library to "Additional Dependencies." The project compiles just fine, and going to the executable and double clicking it runs the application just fine. But in VS2008 when I hit the "play" button I just get an error that "this application failed to start because <library name here> was not found."

What gives?

Where is the dll placed? The working path is likely different when running from visual studio.

digibawb
Dec 15, 2004
got moo?
If you add to a pointer, you offset it by (a multiple of) the size of the type it points to, not by the value you added. So q + 16 will be a memory address 16 * sizeof( int ) bytes further along, not 16 bytes further along. When you shove the pointer into an int, and add to the int instead, all you are doing is increasing the value of the int.

(Ignoring the fact that shoving a pointer into an int isn't the best thing in the world to be doing.)

digibawb fucked around with this message at 18:35 on Feb 6, 2010

digibawb
Dec 15, 2004
got moo?

cronio posted:

XNA is a *lot* slower than direct access to the graphics card

citation required.

Seriously, of all the things for XNA to be slow at on the 360, I really can't see why it would be the rendering. Do you have evidence for this? (Same applies for on Windows tbh)

digibawb
Dec 15, 2004
got moo?
Yeah, unless you are writing your own command buffers, which you don't have access to in XNA, then it's going to be pretty much identical.

No VMX support seems like a much bigger deal, to me anyway.

EDIT: And the limited control of memory...

digibawb fucked around with this message at 12:48 on Apr 10, 2010

digibawb
Dec 15, 2004
got moo?

cronio posted:

Looks like I was partially wrong -- the Direct3D implementation on the 360 is much lower-level than on Windows. In the native API you do get direct access to the hardware though, i.e. you can bypass the Direct3D API or even write directly to the command buffer (and many do). I can't cite anything but this is directly from people who work on the 360.

Direct3D on the 360 is at least a lot better than OpenGL on the PS3 though, which virtually no one uses (that's direct from experience).

The same does not apply on Windows because you don't have the same level of hardware access.

I work on both the 360 and PS3!

I was making the assumption that most 360 developers don't actually end up bypassing the API and rolling their own command buffers, perhaps this is a faulty assumption however. I can certainly see where you are coming from on the PS3 though :) The Windows comment was based on this assumption, in that the managed wrapper around D3D is unlikely to be a bottleneck.

cronio posted:

Yeah, I was assuming the difference was more along the lines of OpenGL vs. libgcm on the PS3. Since that's not the case the differences for the average coder are less, but game developers still do a lot of asm-level optimization (even if they're not writing assembly, analyzing the assembly generated by the compiler).

Also, game developers are dinosaurs, and don't like to change :). They also don't like anything unexpected, which managed languages sometimes provide.

Oh, and they already have millions of lines of asm/C/C++ code. I wouldn't be surprised if a lot of things go the way of Unity (C# as a scripting language -- a lot of developers use Lua now), with the engine still in C/C++.

I'd like to think I'm quite open to change, thank you very much :P

I'd certainly like to see C# in use for game code, though I don't think it's quite practical yet (for us anyway).

I muddle around with XNA at home, and not being able to see what it's doing under the hood will probably become a pain for me at some point, though I haven't hit that yet. Knowing that the JIT will never generate VMX output annoys me, more so than the fact that I just can't write it in intrinsics in the first place. The instruction set for SSE is rather different though, so I can see why this isn't practical either.

Vinterstum posted:

Interpreted languages tend to rely on JITting for their speed but that doesn't work on consoles (all executable code must be signed, and statically compiling them (like Unity for the iPhone does) is pretty variably supported (Unity's solution is very customized and specialized).

I'm pretty sure XNA is JIT'ed even on the 360, fairly certain I saw a post by Shawn Hargreaves stating it was only a couple of days ago in fact.




We might be getting a little off topic here though :D

digibawb
Dec 15, 2004
got moo?

ultra-inquisitor posted:

It's almost certainly a cyclic dependency, you need to forward declare one of the classes.

(file1.h)
code:
#pragma once
#include "file2.h"

struct foo : public bar {};
(file2.h)
code:
#pragma once

struct bar {};

struct foo; // forward declaration for baz

struct baz : public foo {};
Then #include file1.h in file2.cpp

You can't forward declare a type you are using as a base.

digibawb
Dec 15, 2004
got moo?

Pivo posted:

Hello kind folks

I'm using Visual Studio 2005 Professional. I would like to profile some C++ code that I inherited (and runs like poo poo), but I am not fluent enough in x86/enough of a hacker (yet!) to use tools that show me disassembled output. It helps a little, but I'm used to nice profiling in Java and .NET. I want call stacks, I want to drill down into source code. Unfortunately VS2005 Pro doesn't include a profiler. Am I stuck?

Grab a trial version of vtune.

EDIT: Assuming you are running on Intel anyway, otherwise AMD have their own profiler which I can't remember the name of.

There's also http://www.codersnotes.com/sleepy though it's kind of on the basic side.

digibawb fucked around with this message at 09:38 on Jun 9, 2010

digibawb
Dec 15, 2004
got moo?
Does the add function need to modify the state parameter?

digibawb
Dec 15, 2004
got moo?
If you have performance problems, profile, don't guess.

The most obvious answer would be that you just end up with less entries being pushed into the stack => less work to do. Simple test would be to just log how many items you push onto the stack with both the right and wrong versions.

digibawb
Dec 15, 2004
got moo?
Sounds like you are looking for _mm_set1_epi32, that's just a compound operation as well, similar to your initial code. _ps is just for floats.

EDIT: Though it may still be a better implementation...

digibawb fucked around with this message at 13:37 on Dec 10, 2010

Adbot
ADBOT LOVES YOU

digibawb
Dec 15, 2004
got moo?
I missed the fact that your ultimate goal was to perform a fabs, sorry.

You could also look at:

_mm_max_ps( _mm_sub_ps( _mm_setzero_ps(), xyz ), xyz );

as that doesn't require any loads at all, but it depends how your register congestion is I guess!

EDIT: I've been stuck in PPC land for a while, so I'm a bit fuzzy on SSE and its general bottlenecks though, but it might help :)

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