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
Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Why not write an overload that just calls the other one and then adds the const-ness to the result before returning it? You then have the clean external api, and only one place to adjust when the mapping changes.

Adbot
ADBOT LOVES YOU

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

Jabor posted:

Why not write an overload that just calls the other one and then adds the const-ness to the result before returning it? You then have the clean external api, and only one place to adjust when the mapping changes.

You can't call a non-const method from a const one, so somewhere in here you have to use const_cast.

Are member pointers really that bad?

Vanadium
Jan 8, 2005

Why not use the member pointer returning method as a secret implementation detail for two public methods returning const and non-const references?

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

Vanadium posted:

Why not use the member pointer returning method as a secret implementation detail for two public methods returning const and non-const references?

Ooh, I kind of like that idea, actually.

Xarn
Jun 26, 2015
If I understood you correctly, you should just const_cast away the constness internally to support both const and nonconst interface.

This is one of the few cases where it is completely sane and expected to use const_cast.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

Xarn posted:

If I understood you correctly, you should just const_cast away the constness internally to support both const and nonconst interface.

This is one of the few cases where it is completely sane and expected to use const_cast.

Yeah, it's one less method if I just bite it and use const_cast. I just wasn't sure which of the two insane-seeming options I should be using.

Thanks all!

mobby_6kl
Aug 9, 2009

by Fluffdaddy
In VS2013, my solution works perfectly fine in debug mode, but in Release one of the projects fails to compile because it can't find the iostream header :confused: Apparently the error happens in one of the headers from a 3rd party library I include. I checked that all the compiler and liker include directories are exactly the same between the debug and release configurations. Any ideas what I might be missing here?

DrSunshine
Mar 23, 2009

Did I just say that out loud~~?!!!
I'm writing some code that involves putting a specific instance of an object into a vector, with a certain value, followed by another, and another -- as many as the user cares to input.

So it'd be something like:

<Mary's Ball (1), Mary's Ball (2), Mary's Ball (3), Alex's Ball (1), Alex's Ball (2), Alex's Ball (3), John's Ball (1), John's Ball (2), John's Ball (3), ...>

The code that I started with is:

code:
        //Create as many balls as there are names - for each name, generate x ball 
        //objects in the vector, fetch string value and put in each created object
	for(int x=0;x<numNames;x++){
		std::cout << "Input name: ";
		std::cin >> nameFiller;
		for(int i=0;i<b;i++){	
			ballSet[i].getLoad(nameFiller);	//create a ball element at position i with string			
			ballSet.emplace_back(ballSet[i]); //push back object vector with ball element
		}		
	}	
But I'm concerned that it'll just overlap the objects at position i with whatever new value -- Mary's Ball 1 would get replaced by Alex's Ball 1 -- or something like that.

Now, I know that what I need to do is use an iterator, like a for loop, and then pass the last value of the iterator outside so that the next sequence of objects can be placed at the spot where it last left off. But I've been sort of breaking my brain on how is the best way to do this. The way I've been puttering about with this is that it solicits the user for a string to input, runs the loop and places the names, then asks the user for more.

(Bear in mind that I'm pretty much a noob when it comes to C++, I've been sort of teaching myself off and on!)

Thanks in advance!

mobby_6kl
Aug 9, 2009

by Fluffdaddy
Well you could ask for the last element in the vector, but unless I'm missing something about what you're trying to do, this seems a bit more complicated than necessary.
code:
while (get nameFiller) {
   ballSet.emplace_back(ball(nameFiller));
}
depending on your ball object, of course.

DrSunshine
Mar 23, 2009

Did I just say that out loud~~?!!!

mobby_6kl posted:

Well you could ask for the last element in the vector, but unless I'm missing something about what you're trying to do, this seems a bit more complicated than necessary.
code:
while (get nameFiller) {
   ballSet.emplace_back(ball(nameFiller));
}
depending on your ball object, of course.

That ... seems a lot more concise. :stare:

I'm not certain if I quite understand how "while ( get ... )" works, though. Do you have to type in something every time? Like if I wanted 3 balls with "mary" in them, would I have to type "mary" three times?

nielsm
Jun 1, 2009



DrSunshine posted:

That ... seems a lot more concise. :stare:

I'm not certain if I quite understand how "while ( get ... )" works, though. Do you have to type in something every time? Like if I wanted 3 balls with "mary" in them, would I have to type "mary" three times?

In that, "get nameFiller" is pseudocode. Not actual legal C++.

But the emplace_back function just creates a new object at the end of an ordered container.

In your original code, you have a variable "b" that isn't declared/explained. I'm not sure what it's supposed to be, so it's hard to know what you intended the code to do.

DrSunshine
Mar 23, 2009

Did I just say that out loud~~?!!!

nielsm posted:

In that, "get nameFiller" is pseudocode. Not actual legal C++.

But the emplace_back function just creates a new object at the end of an ordered container.

In your original code, you have a variable "b" that isn't declared/explained. I'm not sure what it's supposed to be, so it's hard to know what you intended the code to do.

Oh, "b" was the number of balls per name, "numNames" is the number of names. So for example, if you had 2 names - Mary and Jake - and put in "3", it'd create six balls - 3 carrying the string "Mary" and 3 with "Jake".

mobby_6kl
Aug 9, 2009

by Fluffdaddy

DrSunshine posted:

That ... seems a lot more concise. :stare:

I'm not certain if I quite understand how "while ( get ... )" works, though. Do you have to type in something every time? Like if I wanted 3 balls with "mary" in them, would I have to type "mary" three times?

Yeah, while/get was a bit pseudo-codish for "keep reading names from stdin", you can keep what you have if that works. The other stuff (b, numNames) weren't clear from the code so I ignored that. Sorry for the confusion. I just wanted to simplify this to get to the important part, which is:
code:
ballSet[i].getLoad(nameFiller);	//create a ball element at position i with string			
ballSet.emplace_back(ballSet[i]); //push back object vector with ball element
[strike]This could probably work and create a copy in the vector if you initialized i to the size of the vector on each loop (and getLoad initialized the ball).[/strike] Bad advice, assumed for some reason the objects were already constructed in the vector.

But this is a really strange way to do what you seem to want to do, which I understand is "add a new ball belonging to nameFiller to the vector". Depending on your ball's constructor, you can do that with the single line I posted, which creates the ball belonging to "nameFiller" in the vector.

Unless you want to have the exact same ball 3 times in the vector, in which case you'd need to store pointers/references to the single instance of Marry's ball etc. Welcome to C++! :getin:

mobby_6kl fucked around with this message at 20:33 on Jul 5, 2015

DrSunshine
Mar 23, 2009

Did I just say that out loud~~?!!!

mobby_6kl posted:

Yeah, while/get was a bit pseudo-codish for "keep reading names from stdin", you can keep what you have if that works. The other stuff (b, numNames) weren't clear from the code so I ignored that. Sorry for the confusion. I just wanted to simplify this to get to the important part, which is:
code:
ballSet[i].getLoad(nameFiller);	//create a ball element at position i with string			
ballSet.emplace_back(ballSet[i]); //push back object vector with ball element
This could probably work and create a copy in the vector if you initialized i to the size of the vector on each loop (and getLoad initialized the ball).

But this is a really strange way to do what you seem to want to do, which I understand is "add a new ball belonging to nameFiller to the vector". Depending on your ball's constructor, you can do that with the single line I posted, which creates the ball belonging to "nameFiller" in the vector.

Unless you want to have the exact same ball 3 times in the vector, in which case you'd need to store pointers/references to the single instance of Marry's ball etc. Welcome to C++! :getin:

Oh! So instead of "ballSet[i]" it'd be like "ballset[ballSet.size()]"? That had not occurred to me! Brilliant!

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

DrSunshine posted:

Oh! So instead of "ballSet[i]" it'd be like "ballset[ballSet.size()]"? That had not occurred to me! Brilliant!

That is undefined behavior (out of bounds reference) if you're using a vector, and if you're lucky it will crash. (If you're unlucky, it will post your banking details to 4chan.)

nielsm
Jun 1, 2009



DrSunshine posted:

Oh! So instead of "ballSet[i ]" it'd be like "ballset[ballSet.size()]"? That had not occurred to me! Brilliant!

No, assuming ballSet is a vector<ball> that's just an invalid access past the end, and ought to crash your program.

The vector.emplace_back() function creates a new element at the end and initializes it with the constructor arguments you pass. The vector.push_back() function creates a new element at the end and copies an existing object into it.
Those two functions are the main ways of extending a vector with more elements. You should only use the [x] array indexing notation on a vector when you're accessing already existing elements.

Contains Acetone
Aug 22, 2004
DROP IN ANY US MAILBOX, POST PAID BY SECUR-A-KEY

Contains Acetone fucked around with this message at 17:32 on Jun 24, 2020

csammis
Aug 26, 2003

Mental Institution
This is in C, using clang on OS X 10.10

I'm parsing old 'snd' resources from classic Mac applications and one of the header fields is specified as being an 80-bit extended floating point number:

quote:

The sample rate at which the frames were sampled before compression, as expressed in the 80-bit extended data type representation.

I'm not sure what C type I'm supposed to be using to represent this. cppreference indicates that long double might be the right type, but if that's so, then I'm not sure how I'm supposed to jam the 10 bytes I've got into a data type which is sizeof(long double) = 16 bytes on my system.

code:
uint8_t* pHeader = /* whatever */
long double aiffSampleRate = 0;
memset(&aiffSampleRate, pHeader, 10);
printf("Result: %Lf\n", aiffSampleRate);
Prints 0.000000 from an input buffer of 400DAC44000000000000. I'm not sure what exactly I'm supposed to get for this input buffer but the Apple docs suggest that I'd be getting "22kHz" from an input buffer of 400DADDD1745D145826B so I think zeroes is not it. This part of the header is not very well documented from what I can discover so far :sigh:

Any suggestions?

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
The data is probably big-endian and so needs to be swapped.

C code:
const char data[] = "\x40\x0D\xAD\xDD\x17\x45\xD1\x45\x82\x6B";
char buff[10];
for (int i = 0; i < 10; ++i)
    buff[9 - i] = data[i];
long double aiffSampleRate = 0;
memcpy(&aiffSampleRate, buff, 10);
printf("Result: %Lf\n", aiffSampleRate);
prints out 22254.545455, which is close to 22khz?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

csammis posted:

This is in C, using clang on OS X 10.10

I'm parsing old 'snd' resources from classic Mac applications and one of the header fields is specified as being an 80-bit extended floating point number:

On x86 and x86-64, that's long double. Loads and stores of this type only touch ten bytes, but in C the sizeof is always a multiple of the alignof to simplify array calculations, and it's somewhat faster to give the type a higher alignment because it makes it more likely that the access won't straddle a cache-line boundary.

On other architectures, you would be somewhat screwed, because they do not provide this type. long double on ARM is a 128-bit format. You can, of course, simulate the 80-bit format manually; just know that it has some peculiarities. Fortunately, you did say you're on OS X.

csammis posted:

code:

uint8_t* pHeader = /* whatever */
long double aiffSampleRate = 0;
memset(&aiffSampleRate, pHeader, 10);
printf("Result: %Lf\n", aiffSampleRate);

Prints 0.000000 from an input buffer of 400DAC44000000000000. I'm not sure what exactly I'm supposed to get for this input buffer but the Apple docs suggest that I'd be getting "22kHz" from an input buffer of 400DADDD1745D145826B so I think zeroes is not it. This part of the header is not very well documented from what I can discover so far :sigh:

Any suggestions?

Stop using memset instead of memcpy.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Isn't the 80-bit extended format effectively just the quad-precision format with a mantissa truncated to 64 bits?

sarehu
Apr 20, 2007

(call/cc call/cc)

Jabor posted:

Isn't the 80-bit extended format effectively just the quad-precision format with a mantissa truncated to 64 bits?

63 bits, really.

csammis
Aug 26, 2003

Mental Institution

Plorkyeran posted:

The data is probably big-endian and so needs to be swapped.

C code:
const char data[] = "\x40\x0D\xAD\xDD\x17\x45\xD1\x45\x82\x6B";
char buff[10];
for (int i = 0; i < 10; ++i)
    buff[9 - i] = data[i];
long double aiffSampleRate = 0;
memcpy(&aiffSampleRate, buff, 10);
printf("Result: %Lf\n", aiffSampleRate);
prints out 22254.545455, which is close to 22khz?

Yes! All the rest of the data in these headers is big endian and I didn't even pause to think about this type being swapped too, durr. My data turns out to be 22050.000.

rjmccall posted:

<< architecture information >>

Out of curiousity what the corresponding C type have been on PowerPC? All the example code on Apple's legacy doc site is in Pascal but surely there was a C port for application development. I've never actually written code for a pre-OS X Mac so maybe that's just not true.

rjmccall posted:

Stop using memset instead of memcpy.

Fortunately for my ever-vanishing sanity that was a typo in my post :)

Doc Block
Apr 15, 2003
Fun Shoe
They might have just parsed out the 80-bit format. Or it might be the size of the largest float the old non-Intel Mac FPU could do, like the x87 FPU did.

pseudorandom name
May 6, 2007

The m68k did in fact have an 80 bit FPU.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

sarehu posted:

63 bits, really.

Right, the field occupies 64 bits in memory, but the high bit is always set in what would otherwise be normalized representations. It means you can do, say, multiplication with an ordinary 64-bit multiplier; a 65-bit multiplier is actually a pain in the rear end, as I understand it.

Yeah, the 68k natively supported the same 80-bit format as Intel. PPC does not; long double there is typically a double-double format, primarily implemented in software in terms of doubles, and if you've never heard about this you are probably a happier person for it.

Modulo16
Feb 12, 2014

"Authorities say the phony Pope can be recognized by his high-top sneakers and incredibly foul mouth."

I'm writing a program that takes 2 inputs in the form of 2 characters translates them to binary, packs them together into an unsigned int and provides that translation from decimal to binary, then unpacks them. I am at a loss as to how I can utilize my pointers in the unpack function to finish this project.

C code:
#include <stdio.h>

// function prototypes
unsigned int pack( char x, char y );
void unpack( char *aPtr, char *bPtr, unsigned int pack );
void display( unsigned int value );

int main( void )
{
    char x, y;
    char *aPtr;
    char *bPtr;
    aPtr = &x;
    bPtr = &y;
    unsigned int number;

    printf("Enter two characters: \n");
    scanf( "%c %c", &x, &y );

    printf("\n%c in bits as an unsigned int is: \n", &x);
    display( x );

    printf("\n%c in bits as an unsigned bit is: \n", &y);
    display ( y );

    printf("\n%c and %c pack in an unsigned int:  \n", &x, &y);
    pack( x, y);

    return 0;
}

unsigned int pack( char x, char y )
{
    unsigned int pack;
    pack = x;
    pack <<=8;
    pack |= y;

    printf("\n%c, and %c packed in an unsigned int:  \n");
    display( pack );

}

void unpack( char *aPtr, char *bPtr, unsigned int pack )
{
     char *aPtr;
     char *bPtr;

    *aPtr = value;
    printf("\nThe unpacked characters are %c, and %c:\n", *aPtr, *bPtr);
    value >>= 8;
    *bPtr = value;

}

void display( unsigned int value )
{
    unsigned int n;
    unsigned int Mask = 1<<31;

    for ( n = 1; n <= 32; n++){
        putchar( value & Mask ? '1' : '0');

        value <<= 1;

        if ( n%8 == 0){
            putchar(' ');
        }
    }
    printf("%u = ", value);
}
If anyone could point me to some literature or maybe a helpful hint I'd be eternally grateful.

Modulo16 fucked around with this message at 21:13 on Jul 17, 2015

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...
Maybe C lets you do this without an explicit cast, but you probably want to cast value to char before assigning it to your char *s, and passing *bPtr to printf before you assign it is not going to give you the result you want.

Modulo16
Feb 12, 2014

"Authorities say the phony Pope can be recognized by his high-top sneakers and incredibly foul mouth."

Dessert Rose posted:

Maybe C lets you do this without an explicit cast, but you probably want to cast value to char before assigning it to your char *s, and passing *bPtr to printf before you assign it is not going to give you the result you want.

I'm actually over the use of the pointers. Here's the Mark II, and it does everything I want, but it is giving me symbols instead of the characters in the printf lines inside of the main function. Why in the world is it doing that?

C code:
#include <stdio.h>

// function prototypes
unsigned int pack( char x, char y );
void unpack( char x, char y, unsigned int pack );
void display( unsigned int value );

int main( void )
{
    char x, y;

    printf("Enter two characters: \n");
    scanf( "%c %c", &x, &y );

    printf("\n%c in bits as an unsigned int is:  ", &x);
    display( x );

    printf("\n%c in bits as an unsigned bit is: ", &y);
    display ( y );

    pack(x, y);

    unpack( x, y, pack );
    return 0;
}

unsigned int pack( char x, char y )
{
    unsigned int pack;
    pack = x;
    pack <<=8;//left shifts variable value 8 spaces to left
    pack |= y;//packs y to x using bitwise or.

    printf("\n%c and %c packed in an unsigned int: ", &x, &y);
    display(pack);
}

void unpack( char x, char y, unsigned int pack ) //Unpacks packed unsigned int
{

    unsigned int value;
    value = x;
    printf("\nThe unpacked characters are '%c' and'%c': \n", x, y);

    display(x);

    value >>=8; //left shifts variable value 8 spaces dropping x

    value = y;

    display(y);



}

void display( unsigned int value )
{
    unsigned int n;
    unsigned int Mask = 1<<31;

    printf("\n%u = ", value);

    for ( n = 1; n <= 32; n++){
        putchar( value & Mask ? '1' : '0');

        value <<= 1;

        if ( n%8 == 0){
            putchar(' ');
        }
    }
}

Modulo16 fucked around with this message at 21:51 on Jul 17, 2015

nielsm
Jun 1, 2009



The %c format specification prints an integer as a single character. If you want to print the character code in decimal, use the %d format specifier.

Modulo16
Feb 12, 2014

"Authorities say the phony Pope can be recognized by his high-top sneakers and incredibly foul mouth."

nielsm posted:

The %c format specification prints an integer as a single character. If you want to print the character code in decimal, use the %d format specifier.

that gives me an absurdly large number, not the character. This is kind of weird because function unpack displays the characters properly.

nielsm
Jun 1, 2009



Uh, oh yeah.
Notice the difference between these two lines:

C++ code:
printf("\n%c and %c packed in an unsigned int: "       , &x, &y);
printf("\nThe unpacked characters are '%c' and'%c': \n", x, y);
You're printing the addresses of the variables instead of their values.

Modulo16
Feb 12, 2014

"Authorities say the phony Pope can be recognized by his high-top sneakers and incredibly foul mouth."

nielsm posted:

Uh, oh yeah.
Notice the difference between these two lines:

C++ code:
printf("\n%c and %c packed in an unsigned int: "       , &x, &y);
printf("\nThe unpacked characters are '%c' and'%c': \n", x, y);
You're printing the addresses of the variables instead of their values.

Whoop! :woop: nice catch! Please don't judge me its been a long day.

sarehu
Apr 20, 2007

(call/cc call/cc)
You're passing a pointer.

Edit: You might run into trouble on some inputs because char is signed, also your unpack function isn't actually unpacking anything.

sarehu fucked around with this message at 22:19 on Jul 17, 2015

Modulo16
Feb 12, 2014

"Authorities say the phony Pope can be recognized by his high-top sneakers and incredibly foul mouth."

sarehu posted:

You're passing a pointer.

line 34?

sarehu
Apr 20, 2007

(call/cc call/cc)

SA doesn't have line numbers.

Modulo16
Feb 12, 2014

"Authorities say the phony Pope can be recognized by his high-top sneakers and incredibly foul mouth."

sarehu posted:

You're passing a pointer.

Edit: You might run into trouble on some inputs because char is signed, also your unpack function isn't actually unpacking anything.

I can't use data type unsigned for char though unless, I am mistaken. I just caught that I'm function calling display of x and y instead of having it actually display results.

sarehu
Apr 20, 2007

(call/cc call/cc)
You're converting a "char" to "unsigned int." In C, the signedness of "char" is implementation-specific, but usually it's signed. Suppose somebody inserts a character with code greater than 127, such as é, in many character sets. It'll get a negative value. Suppose that value is "x."

Then, when you convert that to an unsigned int, it'll have the value "x + UINT_MAX + 1."

You probably don't want the packing behavior that your code currently gives you.

DrSunshine
Mar 23, 2009

Did I just say that out loud~~?!!!
I want to compare some variable against a set of numbers inside of a vector that the user can specify. For example:

code:
	myVector = <1, 3, 4>
	if (x == any of the values inside myVector){
		do something
	}
How would I go about doing this? I'm kind of blanking on this, but I'm fairly certain it involves std::find somehow.

Adbot
ADBOT LOVES YOU

Tetraptous
Nov 11, 2004

Dynamic instability during transition.
If you're using C++11, std::any_of does exactly what you want.

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