#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2003
    Posts
    8
    Rep Power
    0

    forcing a pass-by-value


    Sorry for posting yet again so soon, but I'm having some difficulty learning some of the basics of C. Could learn a lot from your advice. I've got a buffer (char[8000]) that is populated with data from a file. I then do two passes over the variable's contents. Once to determine how many lines it contains (\n) and once to store selected data from it into an array. Both passes use the strtok() function.

    I'd like to keep the original buffer variable intact (since strtok() chops up its string argument), and therefore I'm passing it by value to other functions. For some reason the compiler insists that it is being passed by reference, which has the result of destroying the original "untokenized" buffer. My code looks something like this:

    Code:
    //mylib.h
    void scanner(char);
    void extractor(char);
    void readFile(char *);
    
    //main.c
    char buffer[8000];
    
    readFile(buffer); //populates buffer with data
    scanner(buffer); //first pass
    extractor(buffer); //second pass
    
    //mylib.c
    void scanner(char bufferTemp)
    {
       // tokenize bufferTemp
       // ...
    }
    When debugging, both bufferTemp and buffer point to the same memory address, and when I add both variables to the Quick Watch in VS.NET, buffer's type shows up as char[] and bufferTemp's as char *. I've yet to figure out why this happens :confused:

    Sorry I don't have my actual code with me right now. If the problem isn't evident from the codeI posted then I could post all of it in my next reply.

    Thanks.
    Last edited by CoreLEx1; October 11th, 2003 at 03:25 PM.
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Basic law of C life: an array name is equivalent to a pointer.

    Hence, I can think of no simple way to pass an array to a function and keep it read-only; they will always be "call by name".

    However, when you pass to a function a non-array variable, be it scalar or struct, part of the function-call code copies that variable to the stack for the function to use locally, what you refered to as "call by value". So in this case, why not perform that task explicitly?

    Declare another char array to copy the string to for tokenizing. If only one function will use it, then declare it locally as static (so as to keep it off the stack yet still within function scope); else if more than one function will use it then declare it globally.
    Then when you call the function, the first thing the function should do is a strcpy from the original char buffer to the working buffer. And then you simply tokenize the working working buffer.

    Declaring the original buffer as const in the function header should keep the function code from trying to change it, as well as to self-document that that parameter is not to be modified by the function.
    Last edited by dwise1_aol; October 11th, 2003 at 03:46 PM.
  4. #3
  5. Left due to despotic ad-min
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2003
    Posts
    1,044
    Rep Power
    14
    In standard C and C++ it is possible to pass an array to a function that can't be changed: use the const qualifier.

    void function(char * const x);

    The const in this context means that the data pointed to by x can not be changed. This is a hint to the compiler: within function() any attempt to write to the array will trigger a compiler error. It does not put the data into read-only memory at run time (that's something different; the const qualifier prevents code from accidentally changing the argument).

IMN logo majestic logo threadwatch logo seochat tools logo