Menu

strupr bug?

2007-07-24
2012-09-26
  • Nobody/Anonymous

    this will compile but won't run. the console just terminates. I'm using Win98 and 4.9.9.2

    include <string.h>

    char* s = "test";
    printf("%s", strupr(s));

    Azlan

     
    • Nobody/Anonymous

      Cliff,

      First off, thanks for being patient with me on this one and also for your thorough explanation.

      Anyways the compiler does not give any warning when I do this:

      char* s = "test";
      strupr(s);

      It does give out a warning with this:

      const char* s = "test";
      strupr(s);

      Both compile but both fail to execute.

      Now is it possible to change string literals to non-constants? It seems to me that the qualifier "const" is good enough to let the compiler know that the programmer wishes a constant.

      Azlan

       
      • Anonymous

        Anonymous - 2007-07-30

        Thanks - now I have to compile the code to find out what the warnings were when you could have just included them in the post!

        Of course they both fail because they are both wrong! strupr(s) modifies the data pointed to by 's' so it cannot be constant. I am repeating myself now BTW!

        The only correct solution in any compiler is:

        char s[] = "test";

        as in the first response; then s is an array of variable (non-const) strings, arrays 'degrade' to pointers when passed to functions, here it becomes a char*.

        Always use -Wall -Werror compiler options - you get more warnings and the compiler treats them as errors. However that is insufficient to trap this error, to do that you will need to add the -Wwrite-strings option as well (see http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Warning-Options.html#Warning-Options ).

        Consider using all these -Wall -Wformat -Wparentheses -Wshadow -Wextra -Wcast-qual -Wwrite-strings. If using C++ you might want to loose -Wshadow - it can cause more problems than it is worth!

        Clifford

         
    • Nobody/Anonymous

      hmmmm.... can't understand why that would happen!

       
    • Anonymous

      Anonymous - 2007-07-24

      It won't compile because it is not complete. There may be an entirely different problem related to your complete code so you should generally post a more complete example (i.e. something that can be compiled directly).

      However, there is an obvious problem with the fragment you have posted. s points to a string constant, but strupr() attempts to modify the string, and you cannot by definition modify a constant!

      Change to:

      char s[] = "test";
      printf("%s", strupr(s));

      Note that strupr() is a deprecated POSIX function and not a standard library function. You should use _strupr() - it makes no difference but does highlight the fact that it is not standard, which may make maintenance and porting simpler. Since it is trivial, you could also write your own - perhaps using C++ std::string class.

      Clifford

       
    • Nobody/Anonymous

      Hi Cliff!

      well char[] works for strupr like you suggested. thanks.

      Azlan

       
    • Anonymous

      Anonymous - 2007-07-26

      Great, but do you understand why? I.e. have I given you a fish or a net?

      The line:

      char* s = "test";

      is dangerous, it is a non-const pointer to a const object. To make the types agree you need:

      const char* s = "test";

      which may also make it more obvious what your problem was.

      char s[] = "test";

      creates an array and initialises it with the string, so it can be modified (though not made longer!)

      Clifford

       
    • Nobody/Anonymous

      Cliff,

      here's the signature of strupr:

      include <string.h>

      char strupr(char s);

      Now it's clear that the function is expecting char*. I think the library has a bug because Borland executes without a hitch.

      Azlan

       
    • Nobody/Anonymous

      just to add:

      the strupr might not get along with Win98 because thats the OS I'm using. Not too sure about other OSes.

      Azlan

       
    • Anonymous

      Anonymous - 2007-07-30

      I was right, you did not really inderstand. This is not a library bug - the bug was in your code.

      Yes it takes a char NOT a const char. The literal string constant "test" has type const char*, you have assigned a non-const pointer to constant data, it is when an attempt to modify that data is made that the error occurs. The operating system protects that part of the program's memory that contains the data and makes it read-only. Any attempt to write read-only memory causes an exception.

      If it executes with some other compiler, it is either because the compiler is not putting the data in a protected memory segment or because it is generation 16bit code which does not support protection.

      It is erroneous to believe that because code appears to work in one compiler and not another that the compiler it fails in is broken! Usually it is quite the reverse! In this case the code was erroneous, the resulting behaviour from such an error is however undefined - one compiler built code that correctly detected the error, the other did not. I would suggest that in this case the Borland compiler was the weaker product.

      I am not convinced (although I am not in a position to confirm at present) that the error could not be detected at compile time with appropriate warning level settings. I believe that the ability to assign a const pointer to an non const pointer is deprecated and should produce a warning in perhaps a more modern compiler.

      A function such as strupr() has no operating system dependencies other than how the operating system implements memory protection and its behaviour when an access exception occurs.

      Clifford

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.