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
HFX
Nov 29, 2004

Ledneh posted:

A dumb question about debuggers. Are they designed to work only with executables output by particular compilers, or at least a limited set of compilers?

I ask because I've been asked if I'd like to use Visual Studio at work instead of Sun Studio, the caveat being that we still have to use SunCC for compiling for now. So I'd like to use the Visual Studio debugger if possible.

The debugger needs to be able to understand the format of the executable and debugging symbols. You can possibly make it work since there is a gdb for executables compiled with suncc. You will then need the Visual Studio plugin which uses gdb under the hood. Expect a lot of work if you can get it to work.

Adbot
ADBOT LOVES YOU

Optimus Prime Ribs
Jul 25, 2007

I've always wondered.
Take these two functions for example:
code:
void myFooFunctionOne(int src)
{
      //read "src" but do not change its value here
}

void myFooFunctionTwo(const int& src)
{
      //read "src" but do not change its value here
}
Would any significant performance be gained (if any) by using a reference, or is the difference paltry?

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

Optimus Prime Ribs posted:

I've always wondered.
Take these two functions for example:
code:
void myFooFunctionOne(int src)
{
      //read "src" but do not change its value here
}

void myFooFunctionTwo(const int& src)
{
      //read "src" but do not change its value here
}
Would any significant performance be gained (if any) by using a reference, or is the difference paltry?

I think you would actually lose performance by using a reference in this case. If you pass the data by value, then the system just needs to pass on the 4 bytes for the integer, but when you pass by reference it needs to pass on 4 bytes for the address of the integer, which then needs to be looked up to get the actual value of the integer.

shrughes
Oct 11, 2008

(call/cc call/cc)
And on 64-bit systems it will pass an 8-byte address of the 4-byte integer.

Unless the function gets inlined.

Optimus Prime Ribs
Jul 25, 2007

shrughes posted:

And on 64-bit systems it will pass an 8-byte address of the 4-byte integer.

Don't know how I never realised that.
Seems I have some code to fix up then. :downs:

Thanks.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
You should really never pass scalars by const reference; it just means more code, more memory traffic, and less pipelining. This is especially true for platforms which can pass the scalars in question in registers, but it's also true on x86, because some processors actually do some crazy pipelining through the stack, and indirection can kill that.

You should also generally be passing small POD classes — e.g. two floats, an int and a pointer, or something else along those lines — by value.

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe
That's quite interesting to know, I almost always pass small structs as const references, presuming it's quicker than passing by value. You're saying it may actually be slower that way, even with optimization turned on? I'd guess that with a small, inlined function passing by reference would still be faster?

Edit: Know I think about it, would compiler optimizations not say something like "Since passing by value is faster, and the reference is const, I can safely produce pass by value code instead"? I really should study compiler architecture more :(

Gerblyn fucked around with this message at 21:01 on Feb 17, 2011

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Gerblyn posted:

That's quite interesting to know, I almost always pass small structs as const references, presuming it's quicker than passing by value. You're saying it may actually be slower that way, even with optimization turned on? I'd guess that with a small, inlined function passing by reference would still be faster?

If the function is inlined, there should be no difference. If the function is not inlined, passing a small object by value instead of by reference is generally a slight win that can also unblock other optimizations. Obviously this only applies to objects with trivial copy constructors and destructors.

Gerblyn posted:

Edit: Know I think about it, would compiler optimizations not say something like "Since passing by value is faster, and the reference is const, I can safely produce pass by value code instead"? I really should study compiler architecture more :(

In general, compilers are not permitted to change function signatures like this unless they're positive they know every use of the function, and therefore relatively few compilers actually perform this optimization.

Optimus Prime Ribs
Jul 25, 2007

rjmccall posted:

You should really never pass scalars by const reference; it just means more code, more memory traffic, and less pipelining. This is especially true for platforms which can pass the scalars in question in registers, but it's also true on x86, because some processors actually do some crazy pipelining through the stack, and indirection can kill that.

You should also generally be passing small POD classes — e.g. two floats, an int and a pointer, or something else along those lines — by value.

Makes me wonder why the school where I majored in C++ programming didn't cover this.
More times I think about it the more I see dropping out was a good decision. :)

rjmccall posted:

If the function is not inlined, passing a small object by value instead of by reference is generally a slight win that can also unblock other optimizations. Obviously this only applies to objects with trivial copy constructors and destructors.

Would the same be true if a pointer were passed instead?

Paniolo
Oct 9, 2007

Heads will roll.

rjmccall posted:

You should also generally be passing small POD classes — e.g. two floats, an int and a pointer, or something else along those lines — by value.

What would you say is the cutoff where this starts becoming a performance loss? 4 floats? 16 floats?

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

Optimus Prime Ribs posted:

Makes me wonder why the school where I majored in C++ programming didn't cover this.
More times I think about it the more I see dropping out was a good decision. :)

To be fair, we're talking about nanosecond differences in performance here. If you really wanted to optimize your code, looking at this sort of thing isn't generally going to give you much return for your efforts. Good programming courses focus more on things like Order N notation to help teach optimization, since by understanding when to use a binary search instead of a linear search can cut the number of instructions an algorithm does massively, which is 99% of the time far more effective than making a function call a fraction of a microsecond faster.

Not to say the information isn't useful, for example passing by pointer/reference (AFAIK they often equate to pretty much the same thing as far as the compiler's concerned) instead of value might lead to more data cache misses as the code has to do extra memory look ups, which on certain systems (like PS3s or X360s) can lead to trouble.

rjmccall posted:

If the function is inlined, there should be no difference. If the function is not inlined, passing a small object by value instead of by reference is generally a slight win that can also unblock other optimizations. Obviously this only applies to objects with trivial copy constructors and destructors.

Ah, okay, that makes sense. Thanks!

Optimus Prime Ribs
Jul 25, 2007

Gerblyn posted:

To be fair, we're talking about nanosecond differences in performance here.

Oh, I know. Just figured they'd have more comprehensive "dos and don'ts" then they did. And seemed to me like that would be a good thing to point out.

e:

Gerblyn posted:

Good programming courses focus more on things like Order N notation

Yeah for example: I had never even heard of this until I started reading this thread.
That school sucked. :)

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

Optimus Prime Ribs posted:

Yeah for example: I had never even heard of this until I started reading this thread.
That school sucked. :)

Ouch, my course was teaching me that stuff in the second semester.

raminasi
Jan 25, 2005

a last drink with no ice

Optimus Prime Ribs posted:

Oh, I know. Just figured they'd have more comprehensive "dos and don'ts" then they did. And seemed to me like that would be a good thing to point out.

e:


Yeah for example: I had never even heard of this until I started reading this thread.
That school sucked. :)

If the major was literally "C++ programming" it sounds pretty lovely, all right. C++ can be pretty arcane but still doesn't really justify a whole degree.

Optimus Prime Ribs
Jul 25, 2007

GrumpyDoctor posted:

If the major was literally "C++ programming" it sounds pretty lovely, all right. C++ can be pretty arcane but still doesn't really justify a whole degree.

It was specifically tailored for game programming in C++, but a lot of important gotchas and whatnot just weren't covered.
Didn't mean to turn this into a discussion about the lovely college I went to though. :downs:

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Optimus Prime Ribs posted:

Would the same be true if a pointer were passed instead?

With only very rare exceptions, passing around or storing an A& has exactly the same low-level performance impact as passing around or storing an A*. There are obviously high-level semantic differences, but from a low level, there isn't much.

Paniolo posted:

What would you say is the cutoff where this starts becoming a performance loss? 4 floats? 16 floats?

As a rough rule of thumb, I'd say anything larger than 2 pointers is something you should consider passing by reference/pointer. A lot of the specifics here come down to the platforms, though.

For example, the UNIX/MacOSX x86-64 ABI will usually "break down" a struct that's <= 16 bytes and pass the elements in registers, depending on the types involved; so a struct with 4 floats will actually get passed in 2 SSE registers. x86-32 ABIs generally pass everything on the stack, so the balance is different.

Gerblyn posted:

To be fair, we're talking about nanosecond differences in performance here.

Right, absolutely. This is definitely low-level performance. There are legitimate performance gains to be had by tweaking this kind of thing, but often those gains will be totally swamped by higher-level performance factors — choice of algorithm, misuse of concurrency, kernel abuse, poor memory locality, whatever.

Gerblyn posted:

Not to say the information isn't useful, for example passing by pointer/reference instead of value might lead to more data cache misses as the code has to do extra memory look ups, which on certain systems (like PS3s or X360s) can lead to trouble.

Well, if you're using the data a lot, it'll probably be in cache anyway. The bigger concern is aliasing.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

Optimus Prime Ribs posted:

Yeah for example: I had never even heard of this until I started reading this thread.
That school sucked. :)

You may not have heard of it because normal people call it big-O notation or refer more generally to asymptotic performance/bounds

Thrawn200
Dec 13, 2008

"Sometimes I think the surest sign that intelligent life exists elsewhere in the universe is that none of it has tried to contact us." - Calvin & Hobbes
Ok, so hoping for a little homework help here. I'm very new to C++ still (only week 5 of the semester). I think I've got a lot of the basics down but I'm still having some issues with structs and objects. My code isn't compiling with a few errors it NetBeans that I can't figure out.

quote:

main.cpp:43: error: expected primary-expression before ')' token
main.cpp: In function `Player welcome(Player)':
main.cpp:85: error: conversion from `std::string' to non-scalar type `Player' requested

I marked the lines the errors relate to in the code with ***************

Here is my mess of code as it stands right now, I only left in the parts relevant to the errors that someone should need to point out my mistake to me (I think). Some of the code and most of the comments were done for us on a template to begin with. Any help would be greatly appreciated! -


code:
struct Player {
    string name;
    string choice;
    int points;
};

// function declarations (prototypes)
Player welcome(Player); // this function will welcome the player

// global variable declarations and initialization
Player player1 = {"PlayerOne", "rock", 0}; // Instantiate and initialize player1


int main(int argc, char** argv) {

    // call welcome function for player 1
    ***************player1.name = welcome(Player);**********

}


Player welcome(Player) {
    string p1;
    // Begin Game Text
    cout << "Let's get started..." << endl;
    // prompt user for name
    cout << "What is your name?" << endl;
    cin >> p1;
    // if the user enters null then assign PlayerOne as name
    if (p1 == "") {
        p1 = "Player1";
    }

    player1.name = p1;

    *******************return player1.name;****************
} // end welcome function

Nalin
Sep 29, 2007

Hair Elf

Thrawn200 posted:

code:
// function declarations (prototypes)
Player welcome(Player); // this function will welcome the player
In your prototype section, you have declared that you have a function named welcome that takes a Player structure and returns a Player structure. When you provide the implementation, you never give a name to the Player that you pass in.
code:
Player welcome(Player p) {  // Name it p.
That lets you access the passed Player in your code.
Next, in your main function, you try to call welcome. Except, you aren't passing a variable into the function. You are passing the name of the class.

Furthermore, your logic for your welcome function is wrong. The function assigns a name to the global variable player1. It then returns player1's name and sets player1's name to the returned value. That is redundant and there is no need to do that at all.

What you are PROBABLY trying to do is this:
code:
// Define our Player structure.
struct Player {
    string name;
    string choice;
    int points;
};

// welcome will return a string containing the player's name.
string welcome(); // this function will welcome the player

int main(int argc, char** argv) {
    // Create a player.
    Player player1 = {"PlayerOne", "rock", 0};

    // Set the player's name to whatever welcome() returns.
    player1.name = welcome();
}

string welcome() {
    string p1;
    cout << "Let's get started..." << endl;
    cout << "What is your name?" << endl;
    cin >> p1;

    // if the user enters null then assign PlayerOne as name
    if (p1 == "") {
        p1 = "Player1";
    }

    // Return the name we just got.
    return p1;
}

Nalin fucked around with this message at 05:27 on Feb 20, 2011

nop
Mar 31, 2010
Pretty much what Nalin said...

You may want to take a look at this, it details how functions are created and used in C++.

Theseus
Jan 15, 2008

All I know is if there is a God, he's laughin' his ass off.
So I have a small issue. I have a vector union that consists of (partially) the following:

code:
union vector {
    __m128 simd;
    float raw[4];
    vector(__m128);
    vector operator*(const float &);
};
vector vector::operator*(const float & a) {
    return vector(_mm_mul_ps(simd,_mm_set1_ps(a));
}
Now, I was running some unit tests on my vector files, and found an interesting problem. Specifically, this does not appear to behave well - in a test involving looping and reusing the vector a whole bunch, multiplying the vector by some float resulted in non-zero values for some components of the vector that were zero. Not in the floating-point-error range, either - values like -0.65. I changed the function (and prototype) to the following on a hunch:

code:
vector operator*(const float & a) const;
And suddenly, it works perfectly. I have been compiling with -O1 on g++ 4.4.3. My suspicion is that without the const modifying the function, the compiler assumed it was free to modify any of the member variables involved in the function when optimizing it and screwed something up. The problem seems to be fixed, but I'd really like to know why it happened in the first place so I can avoid it in the future. Anyone have any insights?

Grocer Goodwill
Jul 17, 2003

Not just one kind of bread, but a whole variety.

Theseus posted:

So I have a small issue. I have a vector union that consists of (partially) the following:

It's possible you're breaking aliasing rules in your test loop. Try compiling with -fno-strict-aliasing and see if that gives you the results you expect.

Theseus
Jan 15, 2008

All I know is if there is a God, he's laughin' his ass off.

QuickLime posted:

It's possible you're breaking aliasing rules in your test loop. Try compiling with -fno-strict-aliasing and see if that gives you the results you expect.

Removing the function consts and adding -fno-strict-aliasing reproduces the problem exactly as it was prior to having the consts and without -fno-strict-aliasing. Additionally, I tried removing the -O1 flag, and the problem still occurred.

Thrawn200
Dec 13, 2008

"Sometimes I think the surest sign that intelligent life exists elsewhere in the universe is that none of it has tried to contact us." - Calvin & Hobbes

Nalin posted:

In your prototype section, you have declared that you have a function named welcome that takes a Player structure and returns a Player structure. When you provide the implementation, you never give a name to the Player that you pass in.

Stuff


Thanks much, works. I'll have to look it over a few times more as I don't 100% understand all of it yet, but that helps a lot.

I'll also read through that link nop posted.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Theseus posted:

So I have a small issue. I have a vector union that consists of (partially) the following:

It has nothing to do with optimization; this is all overload resolution. Without the const, this operator is not a viable candidate when the LHS of some operation is const. Normally that would mean that this operation shouldn't compile; since that's not happening here, it must be using some different operator; since you didn't mention any other operator, I assume it's probably some builtin operator which ends up being viable because of some conversion operator on vector which you didn't mention.

Also, don't pass floats by const reference.

Theseus
Jan 15, 2008

All I know is if there is a God, he's laughin' his ass off.

rjmccall posted:

It has nothing to do with optimization; this is all overload resolution. Without the const, this operator is not a viable candidate when the LHS of some operation is const. Normally that would mean that this operation shouldn't compile; since that's not happening here, it must be using some different operator; since you didn't mention any other operator, I assume it's probably some builtin operator which ends up being viable because of some conversion operator on vector which you didn't mention.

Also, don't pass floats by const reference.

Awesome, thanks! Am I correct in my guess that the reason I shouldn't pass a float by const reference is because the reference can be as much as eight bytes on a 64-bite machine, while the float would only be four?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
We just had this discussion in this thread. :) On almost (†) any architecture you care about, floats can be passed at least as efficiently as pointers.

(†) Except ARM. On most ARM platforms, it is substantially faster to write a floating-point value to memory, pass the address, and read it back out than to pass it directly. This because ARM's standard ABI does some terrible things for backward compatibility, and nobody realizes they should change it on their amazing new ARM-based platform until it's too late.

rjmccall fucked around with this message at 03:27 on Feb 21, 2011

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe
I ran into a problem today with a template class, and I was wondering if someone could help. What I want to do is write a function that takes an stl vector as a parameter, any stl vector, but which can also do a couple of things with the data type that the vector is storing. Something like:

code:

void ProcessVector(std::vector<_T> myVector)
{
  printf("Vector stores %d items, at %d bytes each\n", myVector.size(), sizeof(_T));
}

Obviously the above doesn't work (the compiler complains that _T is undefined), but I'm terrible at template stuff and am at a loss on how I would go about fixing it. Anyone got any ideas?

OddObserver
Apr 3, 2009
Add template<typename _T> before the void. Also you really want to pass in vectors by const reference; passing them by value is O(n).

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe
Thanks! I'll give it a try when I get it into work tomorrow.

Gothmog1065
May 14, 2009
Okay, I'm currently teaching myself C++ with a crappy "Teach yourself C++" book. So far it's not been too difficult, but I had a question. Is there an elseif in c++? This book has nothing on it. What I'm looking for is this:

code:
if (condition)
   ...
elseif (condition)
   ...
elseif (condition>
   ...
else
   ...
All it shows me is this, which is cumbersome as poo poo:

code:
if (condition}
    expression
else
{
    if (blah)
       Whee!
    else
    {
        if (fuckthis)
            goddamnit
        else 
            sonofabitch
    }
}
I'm still in the basics here, but I was really curious about that.

BigRedDot
Mar 6, 2008

No, but it doesn't need one:
code:
if (foo) {
    // ...
} else if (bar) {
    // ...
} else if (baz) {
    // ...
} else {
    // ...
}

Nalin
Sep 29, 2007

Hair Elf
EDIT: Oh no, beaten!

There is no 'elseif' statement. However, you CAN do this:
code:
if (condition)
  ...
else if (condition)
  ...
else
  ...

Modern Pragmatist
Aug 20, 2008
code:
   if (...)
      ...;
   else if (...)
      ...;
   else if (...)
      ...;
   else if (...)
      ...;
   else 
      ...;
EDIT: Beaten badly

Gothmog1065
May 14, 2009
So it's just whitespace manipulation then? If so, thanks, that works for me.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Gothmog1065 posted:

So it's just whitespace manipulation then? If so, thanks, that works for me.
The idea is that a single instruction is functionally treated the same as a squiggly-brackets-enclosed block containing a single instruction. An "if" is basically a single instruction to conditionally execute another block.

So
if (bla) dosomething;
else dosomethingelse;

works exactly the same way as
if (bla) dosomething;
else if (bla2) dosomethingelse;

or
if (bla) dosomething;
else for (a;b;c) dosomethingelse;


ie. "else if" is not a special instruction in any way, it's treated the same as "else while" or "else for" or "else switch".

Gothmog1065
May 14, 2009

roomforthetuna posted:

ie. "else if" is not a special instruction in any way, it's treated the same as "else while" or "else for" or "else switch".
Okay, I think I get it now. Onward to hopefully less stupid questions in the future!

Scaevolus
Apr 16, 2007

roomforthetuna posted:

The idea is that a single instruction is functionally treated the same as a squiggly-brackets-enclosed block containing a single instruction. An "if" is basically a single instruction to conditionally execute another block.

ie. "else if" is not a special instruction in any way, it's treated the same as "else while" or "else for" or "else switch".

Why did I not realize this before? :downs:

icantfindaname
Jul 1, 2008


Is there any easy way to concatenate a character to a string in C? Specifically, take a character out of another string, iterating through with a for loop. I tried strcat but apparently it needs to be a constant char for that to work. The program is supposed to check whether a string is a palindrome.

code:
for (i = StringLength (InputLine) - 1; i >= 0; i--) {
	if (!(StringEqual (CharToString(InputLine[i]), " "))) {
		//insert concat function here
	}
}

Adbot
ADBOT LOVES YOU

MutantBlue
Jun 8, 2001

icantfindaname posted:

Is there any easy way to concatenate a character to a string in C? Specifically, take a character out of another string, iterating through with a for loop. I tried strcat but apparently it needs to be a constant char for that to work. The program is supposed to check whether a string is a palindrome.

If you just need to detect palindromes you don't need to shuffle any characters around. There are a bunch of examples at Rosetta Code.

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