unexpected stream output with commas

K

Kyle Kolander

Got a strange bug going on here...

// proper includes and additional code here
int x = 2552123;
cout << x;

This results in output like this: 2,552,123
Same behavior with stringstreams.

How can this be happening?
This doesn't always happen... seems like only when we create our executable
with some of our shared libraries (.so).
It works correctly when in main() but not when in our class source files.
When linking with static libraries (.a) it works as expected.

We are developing on AIX with Visual Age 6.0 if that matters.

It's probably something we are doing incorrectly with our shared
libraries... any hints as to what could be causing this?

Thanks,
Kyle
 
V

Victor Bazarov

Kyle said:
Got a strange bug going on here...

// proper includes and additional code here
int x = 2552123;
cout << x;

This results in output like this: 2,552,123
Same behavior with stringstreams.

How can this be happening?
This doesn't always happen... seems like only when we create our executable
with some of our shared libraries (.so).
It works correctly when in main() but not when in our class source files.
When linking with static libraries (.a) it works as expected.

We are developing on AIX with Visual Age 6.0 if that matters.

It's probably something we are doing incorrectly with our shared
libraries... any hints as to what could be causing this?

Default locale setting uses 'do_grouping' that causes 'thousands_sep'
character to be inserted into the output. I don't know much about those
things, but read about locales in general. Could it be your code uses
different locales if a certain .so is loaded. It must set the locale
to something instead of just leaving it unchanged. Read the documentation
for that library, especially the part where it describes locales.

V
 
H

Howard

Kyle Kolander said:
Got a strange bug going on here...

// proper includes and additional code here
int x = 2552123;
cout << x;

This results in output like this: 2,552,123

I take it you don't want the commas? Or do you want periods there? (You
don't specify what it is you actually expected.)
Same behavior with stringstreams.

How can this be happening?
This doesn't always happen... seems like only when we create our
executable
with some of our shared libraries (.so).
It works correctly when in main() but not when in our class source files.
When linking with static libraries (.a) it works as expected.

We are developing on AIX with Visual Age 6.0 if that matters.

It's probably something we are doing incorrectly with our shared
libraries... any hints as to what could be causing this?

Thanks,
Kyle

I'd guess that the shared libraries are specifying locale information, and
that includes whether or not to use thousands separators (and what to use
for them). Check the shared library code (and the settings used to build
them, perhaps?), and see if they're making such specifications. If not,
then perhaps you need to add code to tell them to NOT use the separators?
I'm not familiar with how to do such things, but this should help point you
in the right direction, at least. A Google search might help more.

-Howard
 
K

Kyle Kolander

Victor Bazarov said:
Default locale setting uses 'do_grouping' that causes 'thousands_sep'
character to be inserted into the output. I don't know much about those
things, but read about locales in general. Could it be your code uses
different locales if a certain .so is loaded. It must set the locale
to something instead of just leaving it unchanged. Read the documentation
for that library, especially the part where it describes locales.

V

Thanks guys... I started suspecting locale was the problem after a quick
search of google.
I have also only read a bit about locale settings and never used them.
I'll look into your suggestions.

Thanks again,
Kyle
 
K

Kyle Kolander

Default locale setting uses 'do_grouping' that causes 'thousands_sep'
character to be inserted into the output. I don't know much about those
things, but read about locales in general. Could it be your code uses
different locales if a certain .so is loaded.

I guess we don't understand how the locale could vary based on whether
we use a .so or .a library, because the .a version works and the .so does
not.
Could you please shed a bit more light on this?

Thanks in advance,
Kyle
 
V

Victor Bazarov

Kyle said:
I guess we don't understand how the locale could vary based on whether
we use a .so or .a library, because the .a version works and the .so does
not.
Could you please shed a bit more light on this?

I could if I knew the details. My _guess_ would be that there is some
kind of initialisation code that .so executes when loaded, which might
contain setting the locale. You'll need to ask in a newsgroup where .so
and .a are topical, like a newsgroup for your OS.

I would also strongly recommend contacting the compiler vendor (IBM?).

V
 
H

Howard

Kyle Kolander said:
I guess we don't understand how the locale could vary based on whether
we use a .so or .a library, because the .a version works and the .so does
not.
Could you please shed a bit more light on this?

Thanks in advance,
Kyle

You haven't said where you ger those libraries from. Are you creating them
yourself, or are they some pre-existing libraries? If you're creating them,
it may be that the build settings (makefile, or whatever) has some control
over that aspect. If they're pre-existing, then perhaps whoever built them
might know the difference.

In any case, specifics about library types and the differences between them
are not part of the C++ language specification, and are platform-dependant.
You'd probably get more information in a newsgroup for your operating system
and/or compiler.

-Howard
 
K

Kyle Kolander

Howard said:
You haven't said where you ger those libraries from. Are you creating them
yourself, or are they some pre-existing libraries? If you're creating them,
it may be that the build settings (makefile, or whatever) has some control
over that aspect. If they're pre-existing, then perhaps whoever built them
might know the difference.

In any case, specifics about library types and the differences between them
are not part of the C++ language specification, and are platform-dependant.
You'd probably get more information in a newsgroup for your operating system
and/or compiler.

-Howard

Thanks again... I posted to comp.unix.programmer and comp.unix.aix,
hopefully they will have advice.
They are our own libraries (lots of them written by lots of different
people) ;)
I'll check on the Makefiles.

Thanks,
Kyle
 
K

Kyle Kolander

Howard said:
You haven't said where you ger those libraries from. Are you creating them
yourself, or are they some pre-existing libraries? If you're creating them,
it may be that the build settings (makefile, or whatever) has some control
over that aspect. If they're pre-existing, then perhaps whoever built them
might know the difference.

In any case, specifics about library types and the differences between them
are not part of the C++ language specification, and are platform-dependant.
You'd probably get more information in a newsgroup for your operating system
and/or compiler.

-Howard

Perhaps there is a new twist to this odd behavior...
We added these two lines of code immediately preceding our output of the
int:

string s = cout.getloc().name();
cout << s;

the printout was "C" in both spots (one of which works, and the other does
not).
So it looks like the locale is not being changed. How can the locale be
"C", which is the Default: ANSI-C convention, and still print out numbers
with commas?

So I guess my question would be if there is any other way that streams could
be manipulated into formatting numerics this way?

Thanks,
Kyle
 
A

Alan Johnson

Kyle said:
So I guess my question would be if there is any other way that streams could
be manipulated into formatting numerics this way?

Thanks,
Kyle

The following program demonstrates the only way I know of to create the
behavior you describe. Although it seems unlikely that anyone has done
this in your code, since the locale name is still "C" (when you create a
locale like this, it does not have a name).

-Alan

#include <iostream>
#include <string>
#include <locale>

class group_thousands : public std::numpunct<char>
{
protected :
virtual std::string do_grouping() const
{
return "\3" ;
}
} ;

int main()
{
std::cout.imbue(std::locale(std::cout.getloc(), new group_thousands())) ;

std::cout << 123456789 << std::endl ;
}
 
K

Kyle Kolander

Alan said:
The following program demonstrates the only way I know of to create the
behavior you describe. Although it seems unlikely that anyone has done
this in your code, since the locale name is still "C" (when you create a
locale like this, it does not have a name).

-Alan

#include <iostream>
#include <string>
#include <locale>

class group_thousands : public std::numpunct<char>
{
protected :
virtual std::string do_grouping() const
{
return "\3" ;
}
} ;

int main()
{
std::cout.imbue(std::locale(std::cout.getloc(), new
group_thousands())) ;

std::cout << 123456789 << std::endl ;
}

As it turns out, we were able to eliminate the problem by removing calls
to a performance library called HPM (Hardware Performance Monitor)
Toolkit from IBM. Go figure... *sigh*. Thanks to all for your help!

Kyle
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top