Thread: Just say NO to strlen.

  1. #16
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    because you aren't allowed to create user defined functions with those names.
    Why not? Just change the parameter type to char* and return type to int, and you're all good - no ambiguity. Besides, the library functions are supposed to be in the std:: namespace.

    Code:
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    
    int strlen(char* x)
    {  return 200;  }
    
    int main()
    {
        char* y = "1234";
        for(int i = 0; i < strlen(y); ++i)
            std::cout << y[i];
    
        std::cin.get();
        return 0;
    }
    Output:
    1234 4³I úÚB l³I OåB @´I þÑB T €´I ÖÖB ð´I ’ãB ÍÚB [èB ÆÒB àB IÒB ØB ÓB ‹ÑB dßB oèB 3ÞB {æB $µI láB ©àB ˜ÝB ÆÒB jèB èB ØB ÓB ¼æB íÓB ûèB ÞçB åB
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  2. #17
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Code:
    std::string
    Problem solved!
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  3. #18
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Spoilsport.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #19
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Why not? Just change the parameter type to char* and return type to int, and you're all good - no ambiguity. Besides, the library functions are supposed to be in the std:: namespace.
    Who said this was c++? I might be wrong but I believe that C99 lets you declare variables inside a for loop, which is the only indication that the code might be C++.

    Also changing the return type has no barring on overloading. Changing the parameter char * instead of const char * will cause ambiguity for the user. They might expect to get your function but instead will get the standard function if they use a const pointer or const array.

  5. #20
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Thantos
    Maybe because toupper() and strlen() are defined by the implentation.
    But they aren't built into the compiler, are they? And even if they are, are their specific characteristics built-in too? In some implementations (GNU libc is an example, I think), it is in fact impossible for the compiler to deduce the behaviour of toupper from the code, because the lookup tables are loaded at locale setting time from files on the disk. In other words, the exact behaviour of toupper is not known at compile time.

    Which means that the knowledge, "toupper only returns 0 when passed 0" must be built into the compiler.
    (On a side note, the _toupper macro that appears in the MS CRT ctype.h header doesn't fulfill this guarantee.)

    In other words:

    1) The compiler must have been explicitely told that toupper returns 0 only when being passed 0.
    2) The compiler must either have been explicitely told, or able to deduce from the (suddenly available) code of strlen (which very often is implemented in assembly), that a loop over a sequence passed to strlen and controlled by its return value can never hit a 0 character in its body.
    3) The compiler must either have been explicitely told, or able to deduce from strlen's source, that its return value only changes if a change to the sequence results in a new location of the first 0 character.
    4) The compiler must either have been explicitely told, or able to deduce from strlen's source, that strlen has no additional side effects.

    Given these three pieces of information, the compiler must follow this line of logic:
    Since the loop is controlled by strlen, only non-0 characters will appear in it. The only change to the sequence is the assignment of a value that comes from the same position in the sequence and has been passed through toupper. toupper will only ever return 0 if 0 was passed in, which means that it will never return 0 in this loop, and thus no new 0 characters are introduced inside the loop. Since strlen's return value can never change under these circumstances, strlen can be considered a loop-time constant and can safely be fetched only once.

    I think you're asking a lot, even from modern compilers.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #21
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Changing the parameter char * instead of const char * will cause ambiguity for the user. They might expect to get your function but instead will get the standard function if they use a const pointer or const array.
    Indeed, but it's a possibility that the compiler must take into account.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #22
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ok, well I just ran a test (MSVC 2005 release build):
    Code:
    #include <iostream>
    #include <cstring>
    #include <cctype>
    #include <windows.h>
    
    int main()
    {
        char a_str[1000];
        for(int i = 0; i < 1000; ++i)
            a_str[i] = 'x';
        a_str[999] = '\0';
    
        DWORD j = GetTickCount();
        for(int p = 0; p < 10000; ++p)
        {
            for ( int ix = 0; ix < strlen(a_str); ix++)
            {
                a_str[ix] = tolower( (unsigned char) a_str[ix] );
            }
        }
        DWORD end = GetTickCount() - j;
        std::cout << end << std::endl;
    
        j = GetTickCount();
        for(int p = 0; p < 10000; ++p)
        {
            int n = strlen(a_str);
            for ( int ix = 0; ix < n; ix++)
            {
                a_str[ix] = tolower( (unsigned char) a_str[ix] );
            }
        }
        end = GetTickCount() - j;
        std::cout << end << std::endl;
    
        std::cin.get();
        return 0;
    }
    Output on my machine:
    7031
    47
    Strangely enough, under Debug build:
    3235
    93
    Apparently, the compiler anti-optimized the strlen version for Release build, and optimized the 'proper' version. However, either way the Release build of the strlen version took 149.6 times as long, and the Debug build took 34.8 times as long.
    Last edited by Hunter2; 02-10-2005 at 06:27 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  8. #23
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    Depending on the compiler this may not be as bad as you think. Since the body of the loop doesn't change the length its very possible for the compiler to modify the code so that the function is called once and it saves the return value and uses that in the condition.
    I don't think the compiler can optimize here. Iit doesn't know the side effects strlen has. For instance, strlen could modify errno or some other static variable. Without special code to detect strlen, and if the C library is dynamic or static linked and strlen isn't an inline function, the complier is going to have to assume the worst.

  9. #24
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    strlen killed my cpu and also my family
    You killed them yourself with poor usage

  10. #25
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Yeah, I always see strlen hanging around in back alleys in the shady parts of town.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Playing around strlen :)
    By audinue in forum C Programming
    Replies: 6
    Last Post: 06-13-2008, 03:22 PM
  2. strlen help
    By stewie1986 in forum C Programming
    Replies: 10
    Last Post: 12-04-2007, 12:15 PM
  3. strlen in expressions
    By justforthis1 in forum C++ Programming
    Replies: 4
    Last Post: 10-24-2006, 10:28 AM
  4. strlen()
    By exoeight in forum C Programming
    Replies: 9
    Last Post: 04-01-2005, 10:18 AM
  5. strlen
    By dirgni in forum C++ Programming
    Replies: 6
    Last Post: 12-08-2002, 11:57 PM