Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Locale problem  (Read 8951 times)

0 Members and 1 Guest are viewing this topic.

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
Locale problem
« on: February 07, 2011, 04:22:34 am »
SetString on a sf::Text in sfml2 gets me this
Quote
terminate called after throwing an instance of 'std::runtime_error'
  what():  locale::facet::_S_create_c_locale name not valid

This only happens on a mingw compiled version of my program. A native GCC version doesn't show this problem. The issue likely is that mingw only really has the "C" locale and my environment wants my local locale.

Running the mingw generated executable in wine with LC_ALL=C works. However, I think this should be fixed in SFML itself. The code in Utf.cpp tries to handle this problem, but somehow fails still. Shouldn't it return std::locale("C") if there is a problem?

Also, somehow it never enters the catch block for me.

Laurent, can you look into this?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Locale problem
« Reply #1 on: February 07, 2011, 08:11:34 am »
Quote
Also, somehow it never enters the catch block for me.

Does it really never enter it, or does it enter it and then throws a new exception? There's no reason that the code avoids the catch block on the first line. However it might do on the second one, because there's no catch block to catch it.

Can you tell me which lines work for you (ie. don't throw):
Code: [Select]
std::locale l1;
std::locale l2("");
std::locale l3("C");
Laurent Gomila - SFML developer

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
Locale problem
« Reply #2 on: February 08, 2011, 06:40:46 am »
As for the try-catch:
Code: [Select]
namespace
{
    // Get the current global locale
    std::locale GetCurrentLocale()
    {
        std::cout << "outside before" << std::endl;
        try
        {
            std::cout << "try before" << std::endl;
            return std::locale("");
        }
        catch (std::exception&)
        {
            // It seems that some implementations don't know the "" locale (Mac OS X, MinGW)
            std::cout << "catch before" << std::endl;
            return std::locale();
        }
    }
}


Output:
Quote
outside before
try before
terminate called after throwing an instance of 'std::runtime_error'
  what():  locale::facet::_S_create_c_locale name not valid

abnormal program termination


Your example:
Code: [Select]
#include <iostream>
#include <locale>
#include <exception>

int main(int argc, char* argv[]) {
    try {
        std::locale l1;
    } catch (std::exception& e) {
        std::cout << "l1 exploded" << std::endl;
        std::cout << e.what() << std::endl;
    }

    try {
        std::locale l2("");
    } catch (std::exception& e) {
        std::cout << "l2 exploded" << std::endl;
        std::cout << e.what() << std::endl;
    }

    try {
        std::locale l3("C");
    } catch (std::exception& e) {
        std::cout << "l3 exploded" << std::endl;
        std::cout << e.what() << std::endl;
    }

    try {
        std::locale l4("en_US");
    } catch (std::exception& e) {
        std::cout << "l4 exploded" << std::endl;
        std::cout << e.what() << std::endl;
    }
}


Output:
Quote
l2 exploded
locale::facet::_S_create_c_locale name not valid
l4 exploded
locale::facet::_S_create_c_locale name not valid


For the record, "" implicitly defaults to en_US on my system.

I propose that it should just use "C" whenever it runs on mingw. Mingw with the default stdlib that most people will use has no capability to do locales that I am aware of.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Locale problem
« Reply #3 on: February 08, 2011, 07:38:51 am »
Quote
I propose that it should just use "C" whenever it runs on mingw

I propose to use the default constructor, which simply grabs the current global locale (which should be "C" with MinGW). If people want to use their system's preferred locale, they can call std::locale::global(std::locale("")), or pass std::locale("") to the SFML functions that deal with locales.
Laurent Gomila - SFML developer

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
Locale problem
« Reply #4 on: February 08, 2011, 07:41:55 am »
Well the problem is that my mingw defaults to my actual system locale, is that the default? I didn't do anything special. I just noticed that my application failed when cross-compiled. I also ran it in a native Windows environment and I get the same problem.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Locale problem
« Reply #5 on: February 08, 2011, 07:52:48 am »
Quote
Well the problem is that my mingw defaults to my actual system locale, is that the default? I didn't do anything special.

What do you mean ? Does std::locale().name() returns "en_US"?
Laurent Gomila - SFML developer

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
Locale problem
« Reply #6 on: February 08, 2011, 07:57:45 am »
No, the default constructor of std::locale gives you the "C" locale while the "" constructor gives you the system default (e.g. "en_US"). This is a problem. Also, if the catch was executed, everything would work fine, but it appears to never be executed at all.

I'm not sure about the limitations of exception throwing in a dll, however. Might this be the reason it doesn't work?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Locale problem
« Reply #7 on: February 08, 2011, 08:04:33 am »
Quote
No, the default constructor of std::locale gives you the "C" locale while the "" constructor gives you the system default (e.g. "en_US"). This is a problem.

Why is it a problem? That's what's specified in the standard.

Quote
Also, if the catch was executed, everything would work fine, but it appears to never be executed at all.

I'm not sure about the limitations of exception throwing in a dll, however. Might this be the reason it doesn't work?

I agree, this should be fixed in first place. I don't know if this is the reason, but you can easily check this by switching to static libraries.

However I'll change the code anyway, I think it's better to default to the current global locale, rather than the system's preferred locale. I think it's the default behaviour in the standard library (in iostreams).
Laurent Gomila - SFML developer

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
Locale problem
« Reply #8 on: February 08, 2011, 08:15:55 am »
I meant that it was a problem in this particular case, I don't consider it a problem in general.

Anyway, I'll just be waiting for your fix then.

Silvah

  • Guest
Locale problem
« Reply #9 on: February 08, 2011, 10:04:32 am »
Quote from: "Svenstaro"
I'm not sure about the limitations of exception throwing in a dll, however. Might this be the reason it doesn't work?
Unlikely. Exceptions work perfectly fine within DLLs and even across DLL boundaries if dynamic libgcc is used or if it has been patched to handle cross-module exceptions even without dynamic runtime library (TDM-GCC's libgcc is). What GCC version are you using?

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
Locale problem
« Reply #10 on: February 09, 2011, 03:11:26 am »
I'm using mingw's gcc version 4.5.2. It is built with these settings: http://projects.archlinux.org/svntogit/community.git/tree/mingw32-gcc/trunk/PKGBUILD

I do wonder quite a bit about this behavior I'm seeing. Why doesn't the catch trigger? My build parameters should be fine.

Laurent, I made a minimal temporary fix by replacing the try-catch block with a simple return std::locale(). May I commit that to svn for now?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Locale problem
« Reply #11 on: February 09, 2011, 07:34:37 am »
Quote
Laurent, I made a minimal temporary fix by replacing the try-catch block with a simple return std::locale(). May I commit that to svn for now?

Hmm no, I'll take 5 min to think about it and commit the clean solution once I'm 100% sure it's ok. Because std::locale's default constructor is very fast to execute, I think I can get rid of the whole GetDefaultLocale() thing if we choose this solution.
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Locale problem
« Reply #12 on: February 09, 2011, 05:45:12 pm »
Done ;)
Laurent Gomila - SFML developer

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
Locale problem
« Reply #13 on: February 10, 2011, 01:32:18 am »
Yay, thanks for the quick fix.