Thread: Modify string in function

  1. #61
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    This is what I like. Protect from mistakes.
    Those things don't "protect from mistakes". They help you track mistakes down.

    I just want throw in that generally, I like to code for the fool because often it turns out that I AM that fool myself.
    Read the rest of my post.

    There is a difference between so called "defensive programming" and trying to stand between a fool and his intent.

    So, no, you aren't that fool. You may be a fool; you just aren't that one.

    You would not believe the amount of stupid mistakes I've been able to catch early on this way.
    O_o

    I'm positive that the number is between zero and none.

    The "defensive programming" tactic doesn't serve to add bug checks beyond what you've already thought to check, and if you've already thought to check for a condition it isn't "early".

    I prefer the tactic over other methods myself; I'm not implying some magic elsewhere.

    Soma

  2. #62
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Quote Originally Posted by phantomotap View Post
    I'm positive that the number is between zero and none.

    The "defensive programming" tactic doesn't serve to add bug checks beyond what you've already thought to check, and if you've already thought to check for a condition it isn't "early".
    Well, now you're playing semantics. What constitutes catching mistakes "early", if not that? Example: you write a module of utility functions / classes and build in assertions to verify every invariant you can think of. Over the course of your career, you use that module in many applications / libraries you write. When writing those applications based on your utility module, each time you make a mistake that gets caught right away by an assertion / exception, isn't that "early"?
    If you hadn't previously plastered the module with those assertions, the mistake might have propagated and caused all kinds of fun effects that could have been nigh unto impossible to trace back to the original error. With bad luck, you might even never have noticed it at all.


    P.S. It's acknowledged that you aren't arguing against defensive programming; I didn't overread that.
    Last edited by antred; 06-19-2012 at 02:04 PM.

  3. #63
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    I think part of the point antred is that a better module is flexible enough to be helicopter mom when you are developing and you can remove debugging code when you build a release. See here:
    Quote Originally Posted by phantomotap
    Write your code to be correct when the inputs are correct. You can insert aides to help clients debug. I'm all for that. Just realize that such code will only ever help good programmers develop better code by understanding where they went wrong. (Which means such code can be eliminated in release builds if desired.) You aren't protecting anyone.
    When you are sure that your ducks are in a row and no programmer generated any foolish mistakes using the module, you can remove what helps them. Ideally this also has no effect on the code that is absolutely necessary to sanitize the user's input, not the programmer's input in the implementation.

  4. #64
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Of course. I agree with that.

    P.S. Maybe we should move the parts of this debate that have nothing to do with the OP's question to a separate thread?
    Last edited by antred; 06-19-2012 at 02:22 PM.

  5. #65
    Registered User
    Join Date
    Dec 2007
    Posts
    930
    @Elysia
    ""strcpy(Buf, Tokens[1].c_str());
    I chafe at this line. What happens if Tokens[i].c_str() is longer than the buffer? Same problem as before..."

    It can't be longer because the buffer was assigned to it, so its the same size.
    Do you mean to compare both size before assigning?.

    @Elysia
    "str += Buf;
    I also chafe a this. What if the data you receive cannot fit in the buffer (ie it got truncated)? What if it the send data wasn't null terminated (due to some error or mischievous input)? Disaster! Do not mix strings with buffers! They do not match!"

    I know what and how much I'm sending. It cant be truncated hence the while() loop.
    Whiteflags advised me to use std::strings. So you are saying that I should keep the code with C style functions?


    Code:
    if(iGetSize)
        Total += iReceived;
    else
        TotalSize -= iReceived;
    The purpose of this is that until I didnt get 12356$data up to the $ delimiter, I cannot know the TotalSize to get so I have to put it into
    Total what I recieved until I can check the final size.
    Its because maybe I only get 1 or 2 bytes in the first loop. There is no guarantee how many bytes I get by loop.
    But you are right I will not use unsigned and check for negative instead.
    Last edited by Ducky; 06-19-2012 at 02:23 PM.
    Using Windows 10 with Code Blocks and MingW.

  6. #66
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Quote Originally Posted by Ducky View Post
    I know what and how much I'm sending. It cant be truncated hence the while() loop.
    Andred advised me to use std::strings. So you are saying that I should keep the code with C style functions?
    That was before you said you had to use character arrays to pass into the recv() function. std::string is not suited for that purpose, because recv() just wants the address of an array to which to write incoming data. You can't (without dirty hackery *) say to an std::string object: "Hey, give me a pointer to your internal character buffer! I wanna write stuff to it."

    Either use a vector or just a plain array for that.


    EDIT: * Well, you could, but you really shouldn't. Otherwise it might happen that the string's length() method's return value disagrees with the length of the actual string data contained in its internal buffer.
    Last edited by antred; 06-19-2012 at 02:30 PM.

  7. #67
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    As far as I know, string doesn't really force you to use 0 terminated data either, but the vector interface is a lot more natural I suppose. You'd be using very similar methods either way.

  8. #68
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Quote Originally Posted by whiteflags View Post
    As far as I know, string doesn't really force you to use 0 terminated data either
    Possibly not, but I suspect there might be some confusion in cases where

    • std::string::empty() returned false, but std::string::c_str() returned a string whose first character is \0
    • std::string::length() disagrees with std::strlen( std::string::c_str() );

    and so on.

  9. #69
    Registered User
    Join Date
    Dec 2007
    Posts
    930
    @Andred
    Since I know exactly what and how much I'm sending I do not risk any overflow or underrun.
    And I don't want to get any internal pointer in the string, I already have a delimiter in it.
    I think the code is fine as it is.

    @whiteflags
    String is much simpler to use than vector.
    And for this little piece of code it wont make any difference.
    Using Windows 10 with Code Blocks and MingW.

  10. #70
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by antred View Post
    Possibly not, but I suspect there might be some confusion in cases where

    • std::string::empty() returned false, but std::string::c_str() returned a string whose first character is \0
    • std::string::length() disagrees with std::strlen( std::string::c_str() );

    and so on.
    Probably not , as:
    Code:
    std::cout<<std::strlen(std::string("").c_str());
    prints 0.

  11. #71
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Well, now you're playing [...] noticed it at all.
    O_o

    I don't know that I am playing with semantics. I am being me though which is usually as much of a problem.

    I think, more likely, you misunderstood "when" and "where" I was referring to with my poorly playful statement.

    *shrug*

    When I quoted "early" I was not teasing "later".

    I was not even really teasing "just in time" though that would be more appropriate.

    To put it another way, my suggestion was that not thinking of an error situation constitutes a failure with no relationship to time.

    Or yet another way, my assertion, you'll have to forgive that one, is that reasoning about error conditions is a steadfast requirement not an option to be claimed "earlier" or "later".

    I argue, always and forever, that code begins in the mind aeons before it finds the compiler.

    When you are still reasoning about code, before you start typing at all, is the correct "when" to start hunting bugs neither "earlier" nor "later".

    Maybe we should move the parts of this debate that have nothing to do with the OP's question to a separate thread?
    So... almost all of them? ^_^;

    *shrug*

    It doesn't matter; it should be moved.

    Maybe a moderator will be free enough to move it.

    I'm done with this though because I've already spent way too much time on it today.

    Soma

  12. #72
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    And for this little piece of code it wont make any difference.
    @Ducky: Yes, oh yes, oh yes it does.

    The `std::vector<unsigned char>' will be easier for you to use correctly.

    Please use `std::vector<unsigned char>' or we will probably be back helping you soonish with the `std::string' approach when you've crashed your code.

    Probably not , as: prints 0.
    Of course, but you've not added arbitrary bytes to the contained string as `read' might.

    When the contained data is "\0\0\0\0\0\0\0Hello, World!\0\0\0" the results will not be so meaningful.

    Soma

  13. #73
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Quote Originally Posted by manasij7479 View Post
    Probably not , as:
    Code:
    std::cout<<std::strlen(std::string("").c_str());
    prints 0.
    Think about the difference between what you've done there and the scenario that I just described. To illustrate:

    Code:
    #include <iostream>
    #include <string>
    #include <cassert>
    #include <cstring>
    
    void funcThatRequiresNonEmpty_C_String( const char* string ) // <-- And yes, some poorly written C style APIs assume on blind faith that they get a non-empty string.
    {
        assert( std::strlen( string ) > 0 );
    }
    
    int main()
    {
        const std::string badIdea( 20, '\0' );
        
        if ( ! badIdea.empty() )
        {
            funcThatRequiresNonEmpty_C_String( badIdea.c_str() );
        }
    }

  14. #74
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Quote Originally Posted by phantomotap View Post
    I don't know that I am playing with semantics. I am being me though which is usually as much of a problem.


    Quote Originally Posted by phantomotap View Post
    I think, more likely, you misunderstood "when" and "where" I was referring to [...]
    Ah well, fair enough anyway. I get the feeling we're in agreeance that defensive programming and thinking about invariants while designing the code is a good thing. Whether the errors caught that way are caught "early", "late" or somewhere between is mostly a philosophical subject to me.

  15. #75
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    @Ducky:
    Make no assumptions about the layout of the data, or as little as possible. This protects you from when you make possible changes to how you send and receive data.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. modify function pass it array
    By a.mlw.walker in forum C Programming
    Replies: 12
    Last Post: 08-01-2011, 04:03 AM
  2. Replies: 15
    Last Post: 05-11-2011, 05:06 PM
  3. how to modify strcmp function
    By asteroid1122 in forum C Programming
    Replies: 6
    Last Post: 08-23-2009, 12:24 AM
  4. modify pointer to a string/character constant.
    By xsouldeath in forum C Programming
    Replies: 12
    Last Post: 10-03-2007, 02:41 AM
  5. modify has function from string parameter to templates...
    By rusty0412 in forum C++ Programming
    Replies: 2
    Last Post: 01-13-2005, 08:02 PM