This is the mail archive of the gsl-discuss@sources.redhat.com mailing list for the GSL project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Parameter vectors declared as const in minimized functions


On Tue, 4 Jan 2005, Andrej Prsa wrote:

> int f (const int *arg)
>   {
>   if (*arg > 5) *arg -= 5;
>   return *arg+2;
>   }
> 
> int main ()
>   {
>   int var = 10;
>   printf ("Result: %d\n", f(&var));
>   return 0;
>   }
> 
> Now obviously you pass to f() whatever (int *), but the if statement in
> the f() function cannot be done, because arg is read-only, as is assured
> by the keyword const.

I'm not quite certain, but I think you are confusing what is constant
here.  arg IS read-only -- it isn't affected by anything you do to *arg.
int *arg means arg contains an address; in your example, the address of
the variable "var", and *arg is a reference to its contents.  var exists
in the local memory space of main.  When you pass its address to f as
"const int *arg", you promise not to to do something like:

int f (const int *arg)
  {
  int my_var;
  arg = &myvar;
  if (*arg > 5) *arg -= 5;
  return *arg+2;
  }

(reassign a new value to arg) or

int f (const int *arg)
  {
  if (*arg > 5) arg++;
  return *arg+2;
  }

(increment arg so that it points at the next int location in memory
contiguous to var, whereever that might be and whether or not you own
it).

Hopefully it is obvious why you wouldn't "generally" want to do either
of these anyway.  I expect that the main reason for declaring it this
way is compiler efficiency, since function variables are all copies of
the associated arguments anyway and are disposed of silently when the
routine goes away (hence the need for pointers in the first place in
order to permit a function to modify a value in the calling routine).
Perhaps security and code quality too -- if you DO try to increment arg,
unexpected and unsafe things are likely to occur.

That is, I think that the order of precedence is const (int *arg) (the
integer pointer itself cannot change to point to some other value), not
const int (*arg) (the contents of memory pointed to by *arg cannot
change).

The compiler will almost certainly not complain about:

int f (const int *arg)
  {
  int *my_arg;
  my_arg = arg;
  if (*my_arg > 5) *my_arg -= 5;
  return *my_arg+2;
  }

(where I don't assert that doing this makes any sense, only that it will
have precisely the same effect as the original code snippet but will
leave the *arg per se alone.)

If I'm wrong about any of this I'd love to know about it.  I have three
different online C manual/tutorial/textbooks bookmarked, but they don't
discuss the order of precedence between const type (*)var, and given the
role of pointers in C, declaring something to be const int *arg is
pretty oxymoronic.  One NEVER uses pointers unless one expect to vary
them, and I'm not certain that a compiler would know what to do with:

 int y;
 const int *var=&y;

(which is the only sort of usage that complies with the rules for a
const declaration.)

In the gcc tutorial in particular, although they do have a vector/array
that is declared as const, an array is not the same as a pointer.  By
assigning:

  int var;
  var = 10;

in the calling code, you've made it clear that var itself is NOT a
const, as a const type variable "must be assigned a value when it is
declared".

With all that said, it isn't terribly clear why one would ever care
about having a const type declaration in a subroutine.  If it indeed
must BE assigned a value when it is declared (generally so it can be
compiled into the code) it makes it kinda hard to use to pass in a
variable value, and nothing you can declare in an argument list will
directly affect any variable in the calling function even if it is
changed, as the transient variable list memory itself is discarded on
return no matter what you do it.

   rgb

-- 
Robert G. Brown	                       http://www.phy.duke.edu/~rgb/
Duke University Dept. of Physics, Box 90305
Durham, N.C. 27708-0305
Phone: 1-919-660-2567  Fax: 919-660-2525     email:rgb@phy.duke.edu



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]