toupper() & tolower() problem?

This is a discussion on toupper() & tolower() problem? within the C++ Programming forums, part of the General Programming Boards category; The facts are that, when the expressions are standalone, pre-increment is no worse than post-increment in terms of efficiency, and ...

  1. #31
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,543
    The facts are that, when the expressions are standalone, pre-increment is no worse than post-increment in terms of efficiency, and can even be better. Therefore, there is no advantage in using post-increment instead of pre-increment in such a context. To say "pick whichever one suits you best" is thus bad advice.
    This is the heart of the discussion.
    Neither is better than the other in this context, hence use whatever you think is best suits this context fine, I think.

    But honestly, if you wish to pursue this, go right head. I have no desire to continue this.
    It is, as it always has been, an opinion. Arguments can go into discussion forever and I always end up on the defending side.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #32
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,633
    Quote Originally Posted by Elysia
    This is the heart of the discussion.
    Neither is better than the other in this context
    What context are you talking about? If you mean the original post, then yes, we have already agreed that standalone pre-increment and post-increment for built-in (and pointer) types result in no difference in efficiency.

    Quote Originally Posted by Elysia
    hence use whatever you think is best suits this context fine, I think.
    Assuming that I guessed "this context" correctly, then they both suit this context equally well. Since in the more general case of standalone increment pre-increment could be better and is no worse (assuming normal semantics), it should be appropriate to use the increased consistency to break the tie in favour of pre-increment.

    Quote Originally Posted by Elysia
    But honestly, if you wish to pursue this, go right head. I have no desire to continue this.
    You do not even have a desire to respond to this?
    Quote Originally Posted by laserlight
    In what way can this particular habit (of using pre-increment instead of post-increment where the choice does not matter other than possible avoidance of needless inefficiency) cause problems?
    Quote Originally Posted by Elysia
    It is, as it always has been, an opinion.
    Of course, it is a matter of style rather than correctness. But style can have an objective basis, or it can be founded upon purely subjective taste.

    Quote Originally Posted by Elysia
    Arguments can go into discussion forever and I always end up on the defending side.
    Well, if you did not make such inane statements as the one in post #27 then you would not have to defend them
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #33
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,182
    Quote Originally Posted by Elysia
    Arguments can go into discussion forever and I always end up on the defending side.
    Try attacking, too!

    What's bad about pre-increments?

  4. #34
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827

    Wink

    Quote Originally Posted by saqib_ View Post
    The following code converts the string copied to uppercase and then to lowercase again.

    Code:
    // Convert a string to uppercase & lowercase
    
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    
    using namespace std;
    
    int main()
    {
     char str[80];
     int i;
     
     strcpy(str, "This is copied to str");
     for(i=0;str[i];i++)
                        str[i]=toupper(str[i]);
     cout << str;
     
     for(i=0;str[i];i++)
                        str[i]=tolower(str[i]);
     
     cout << "\nOriginal str was ( " << str << " )\n\n";
     
    system("pause");
    return 0;
    
    }
    The problem is I cannot make it work without a second for loop. I don't want to use the second for loop, instead any other way if possible.
    Quote Originally Posted by Kinshara View Post
    I don't really sure about what am I thinking..
    why don't you use, strupper and strlower?
    Quote Originally Posted by saqib_ View Post
    Well it would be very useful if you show me how to do it, as I am a beginner in C++. I have not used strupper and strlower before.
    Quote Originally Posted by RockyMarrone View Post
    Well the problem lies with your second condition of for loop

    it should be i < strlen(str)

    your modified code will be like this

    Code:
     for(i=0; i < strlen(str); i++)
    Quote Originally Posted by whiteflags View Post
    If you're willing to make more copies of the original string, you can just copy a lowercase version and an uppercase version, all using one loop.
    Quote Originally Posted by RockyMarrone View Post
    that is one point of optimization and others what i can suggest use ++i instead of i++ and user memset.
    Quote Originally Posted by whiteflags View Post
    None of those things are optimizations, and even if they were, strlen being called every iteration makes it irrelevant.
    Quote Originally Posted by RockyMarrone View Post
    I don't know how can u say that

    for post and pre increment
    Quote Originally Posted by saqib_ View Post
    Guys can't we use the transform function here like the one used in the following code?
    Code:
    #include <iostream>
    #include <algorithm>
    #include <cctype>
    #include <cstring>
    #include <cstdlib>
    
    int main()
    {
        char string[100];
        char upString[100];
        char lowString[100];
        
        strcpy(string, "I have a nice red house and you're not gonna take it from me!");
        
        unsigned int stringLength = 0;
        for (unsigned int i = 0; string[i] != '\0'; i++)
            stringLength++;
        
        std::cout << "The original: " << string << "\n\n";
        std::cout << "Now applying transform() to uppercase...\n\n";
        
        std::transform(&string[0], &string[stringLength], &upString[0], toupper);
    // This is equal to
    // std::transform(string, string + stringLength, upString, toupper);
    // but might make more sense
        upString[stringLength] = 0;
        
        std::cout << "upString: " << upString << "\n\n";
        std::cout << "Now applying transform() to lowercase (it's a verb, yes)...\n\n";
        
        std::transform(&string[0], &string[stringLength], &lowString[0], tolower);
        lowString[stringLength] = 0;
        
        std::cout << "lowString: " << lowString << "\n\n";
        
        system("pause");
        return 0;
    }
    Quote Originally Posted by whiteflags View Post
    >> i dont know how you can say that

    What do you think takes more time, counting the number of characters in the string or copying a single integer? Now square that estimate, because you called it for every iteration. Thinking in theory is fine, but you should use common sense first.

    >> Guys can't we use the transform function here like the one used in the following code?

    What do you think
    Quote Originally Posted by cpjust View Post
    For simple types like ints, the compiler would optimize i++ to ++i for you anyways, but yes, I always use ++i in for loops anyways.
    Quote Originally Posted by saqib_ View Post
    Yes, we should prefer ++i to i++.
    Quote Originally Posted by Elysia View Post
    No, we should not prefer one over the other. It is a matter of style and where one form fits better than the other. Neither is better than the other.
    Quote Originally Posted by saqib_ View Post
    I see. Thank you.
    Quote Originally Posted by King Mir View Post
    It matters for non-pointer iterators, so it's a good habit to use ++i, so that ++itr is consistent.

    Re:the OP
    Just have a seperate buffer for the uppercase and lowercase strings.
    Quote Originally Posted by Elysia View Post
    Except when you want to do
    T a = i++;
    So they have different uses.
    And usually i++ or ++i does not matter - the compiler can usually optimize such things and the speed impact is usually negligible.
    Quote Originally Posted by King Mir View Post
    I agree that if you use the result, then the choice is based entirely on that. I'm talking about cases where the result is not used.

    The compiler can only optimize if the operator is inline. There is no reason to assume that the compiler will choose to do this for say map iterators. Best to have the same habits for everything.
    Quote Originally Posted by C_ntua View Post
    They don't do the same thing anyway. The only situation that I can think of that they do same thing is when the value of the variable is not used. Like "++i;" or "i++;". In those cases the compiler will optimize, because it is too simple not to do so. You simply don't care about the "pre" vs "pro". You just have an increment.

    For custom type (classes) you can have something like this

    Code:
    myClass& operator++() //pre-increment
    {
        this->value += 1;
        return *this;
    }
    
    myClass operator++(int)  //post-increment
    {
        myClass temp(*this);
        this->value += 1;
        return tmp;
    }
    So the post increment will have to make a copy. The compiler will probably not optimize in this case.

    So post-increment is guaranteed to be equal or faster.

    If you know that they are the same (because they are fundamental types for example) then it is a matter of style. But that is an if. If you see a code that has
    Code:
    for (i=0; i < count; i++) ...
    then "i" might not be an int. It can be a custom class. In which case the "i++" would probably be wrong.
    if you see
    Code:
    for (int i=0; i < count; i++) ...
    then you know "i" is an int and no problem.

    If you don't overload ++ or -- I don't think you will have to worry which one to use...
    Quote Originally Posted by King Mir View Post
    If you're using i, then it better be an int (or similar). Iterators names should have at least a few characters to them.

    Just saying.
    Quote Originally Posted by Elysia View Post
    The notion that optimizations cannot be done if the the code isn't inline and the compiler cannot see it at the time of instantiation is wrong. There is link-time optimizations that can be done. Both MSVC and GCC supports this.
    Habits are a subjective thing, also. One should always adapt habits best to oneself. Always using ++i, for example, is also a subjective thing. Whether we use i++ or ++i when the statement is used on its own is meaningless to debate; it's a preference.
    Whether it's an iterator, an object or an integer doesn't matter.

    All I am saying is that when using ++i or i++ alone, it is a matter of style.
    When you use objects, it still probably does not matter, but even if you want to use ++i, I still do not agree it is a good habit to always use. So ++i is NOT always better than i++ (which was the original statement). They have different uses, so use them accordingly.
    Quote Originally Posted by King Mir View Post
    Your claim, that MSVC and GCC will eliminate temporaries that are used solely for the return value of a function when a function is called from another file and the result is not used, is hard to believe. It's not an easy optimization to do, and would require two object code functions to be generated for each C function.

    ++i is always no worse than i++, when the return value is unused. That's the point I'm supporting. Therefor using ++i in such cases is a better habit.

    Preference does not exist for new users. Certainly, I have no problem with you using i++ in your code. But for a novice to C, who does not have a preference, it is best to be introduced to the best practice.
    Quote Originally Posted by Elysia View Post
    I do not claim they will optimize temporaries. I claim they can optimize without seeing the function.
    But for the best practice bit, I simply disagree. Habits can cause problems, but they are also individual.

    Btw, for that matter, for this code:

    Code:
    #include <iostream>
    
    class Iterator
    {
    private:
    	int m_i;
    
    public:
    	Iterator(): m_i(0) {}
    	Iterator& operator ++ () { m_i++; return *this; }
    	Iterator operator ++ (int) { Iterator temp(*this); m_i++; return temp; }
    	bool operator < (int i) { return m_i < i; }
    	int operator * () { return m_i; }
    };
    
    int main()
    {
    	for (Iterator it; it < 10; it++)
    		std::cout << *it;
    	for (Iterator it; it < 10; ++it)
    		std::cout << *it;
    }
    I get this assembly output with optimizations (even better with inlining):
    00D21010 inc dword ptr [eax]
    00D21012 ret

    00D21020 mov ecx,dword ptr [edx]
    00D21022 mov dword ptr [eax],ecx
    00D21024 inc ecx
    00D21025 mov dword ptr [edx],ecx
    00D21027 ret

    Hardly expensive.
    Quote Originally Posted by laserlight View Post
    It may well be the case that even if the relevant optimisations are not performed, and there is actually a penalty in efficiency, that this penalty does not matter because it has a negligible effect compared to the overall execution cost. But since this possible inefficiency can be avoided without obscuring the code in any way, it is a matter of good style to use ++i instead of i++ where the expressions are standalone.


    I agree, if the expression is not standalone, it may be the case that post-increment is preferable.


    No, the original statement was just a suggestion by RockyMarrone to use ++i instead of i++. The part about it being an optimisation in this case may be misguided, but it was not a statement that ++i is always better than i++. saqib_'s recommendation that we should prefer ++i to i++ probably comes closest, but still the word "prefer" is not so strong as to imply that ++i is always better than i++.


    Are you sure? Such an optimisation sounds like it can change the meaning of the program, since ++i and i++ may well do completely different things.


    In what way can this particular habit (of using pre-increment instead of post-increment where the choice does not matter other than possible avoidance of needless inefficiency) cause problems?
    Quote Originally Posted by Elysia View Post
    A good point, and one I do not argue. It may be preferable to use ++i when using objects.


    I interpreted the way the conversation was going akin to:
    Use only ++i because it was/is better in some way i++, so we should always use it whenever possible.
    That is the claim I refute, because that is a matter of style.


    I was talking generally, not about removing the returning of a temporary.
    The link-time code generation option of MSVC allows the compiler to inline functions in other source files, and after inlining them, it can also perform some more optimizations on that inlined code. GCC also has such an option some time ago.
    So the claim that code cannot be optimized unless the compiler can see it is untrue. But any claim that the compiler will and can optimize away the returning of temporaries is mostly likely untrue. I have yet to see such a compiler.


    Sigh. I am voicing an opinion here, not an argument.
    Which is better is a matter of much debate, one of which I would rather not get into.
    But I do not believe in habits. I believe in free style - allowing the programmer to choose what is best for him or her.
    Quote Originally Posted by laserlight View Post
    Heheh...

    In my opinion, one needs to have some idea of the good habits in order to "free style" properly. Otherwise, the "free style" would just be the exercise of bad habits.
    Quote Originally Posted by cpjust View Post
    In a Coding Standard at a previous company, I believe this is how they worded that particular issue:


    Since ++i and i++ are equally easy to read, using ++i does not fall into the category of premature optimization, and it's always better than or equal to i++ whether the compiler optimizes it or not.

    Just because the language is called C++ doesn't mean you should prefer post-increment.
    Quote Originally Posted by Elysia View Post
    Just because ++i is better does not mean you should prefer it over i++.
    Quote Originally Posted by laserlight View Post
    Kindly elaborate, otherwise your statement just sounds like nonsense.
    Quote Originally Posted by Elysia View Post
    I see it like a debate over C vs C++. Prefer whichever one suits you best.
    Quote Originally Posted by laserlight View Post
    Then you are just ignoring the facts in order to maintain your unreasonable position.

    The facts are that, when the expressions are standalone, pre-increment is no worse than post-increment in terms of efficiency, and can even be better. Therefore, there is no advantage in using post-increment instead of pre-increment in such a context. To say "pick whichever one suits you best" is thus bad advice.

    It would be good advice when we are faced between the choice of a standalone use of pre-increment along with another expression, or the combined expression with post-increment, in which case the choice is one of style: do you prefer to have two statements, or a single slightly more complex statement? However, the phrase "just because ++i is better" rules this situation out, since in this situation it is not clear if "++i is better".
    Quote Originally Posted by Elysia View Post
    This is the heart of the discussion.
    Neither is better than the other in this context, hence use whatever you think is best suits this context fine, I think.

    But honestly, if you wish to pursue this, go right head. I have no desire to continue this.
    It is, as it always has been, an opinion. Arguments can go into discussion forever and I always end up on the defending side.
    Quote Originally Posted by laserlight View Post
    What context are you talking about? If you mean the original post, then yes, we have already agreed that standalone pre-increment and post-increment for built-in (and pointer) types result in no difference in efficiency.


    Assuming that I guessed "this context" correctly, then they both suit this context equally well. Since in the more general case of standalone increment pre-increment could be better and is no worse (assuming normal semantics), it should be appropriate to use the increased consistency to break the tie in favour of pre-increment.


    You do not even have a desire to respond to this?



    Of course, it is a matter of style rather than correctness. But style can have an objective basis, or it can be founded upon purely subjective taste.


    Well, if you did not make such inane statements as the one in post #27 then you would not have to defend them
    Quote Originally Posted by cyberfish View Post
    Try attacking, too!

    What's bad about pre-increments?
    Just thought I'd line up all of the posts on a single page....

  5. #35
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,543
    And that is funny, because...?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #36
    Registered User DeadlyWarrior's Avatar
    Join Date
    Dec 2009
    Location
    Pakistan
    Posts
    5

    Check this

    Assalam-O-Alaikum.

    Code:
    struct Edge
    	{
    		CString Linked_MAC;
    		int     Weight;
    
                             Edge   *Next;  
    
    	}*Edge_Head;
    
    
    	struct Node
    	{
    		CString MAC_Address;
    		Edge   *Link;
    
    		Node   *Next;
            
    	}*Node_Head;
    I am using the above two structs for my 2D Link List

    Now i have write a function for destroying list completely but its not working properly!!!!

    Code:
    void CDataStructure::Destroy(void)
    {
    	Node *traverseN = new Node();
    	Node *tempN     = new Node();
    	Edge *tempE     = new Edge();
    	Edge *traverseE = new Edge();
    
    	
    	traverseN = Node_Head;
    
    	while(traverseN != NULL)
    	{
    		if(traverseN->Link != NULL)
    		{
    			traverseE = traverseN->Link;
    
    			while(traverseE != NULL)
    			{
    				tempE = traverseE;
    				traverseE = traverseE->Next;
    				delete tempE;
    			}
    		}
    
    		tempN = traverseN;
    		traverseN = traverseN->Next;
    		delete tempN;
    	}
    
    
    
    }
    Waiting for your suggestionssssss.--------

    Thanks in Advance.
    Last edited by DeadlyWarrior; 12-04-2009 at 10:48 AM.

Page 3 of 3 FirstFirst 123
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 10:22 AM
  2. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  3. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  4. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  5. tolower function problem
    By Jack-Bauer in forum C++ Programming
    Replies: 6
    Last Post: 05-18-2006, 11:17 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21