2

My first ever question. On 'maning-up' to learn c++ I have myself in a tangle over scope. My understanding is that variables defined in functions should cannot be passe dout of scope. But I have been this like the below A LOT and it works everytime with no problems. What am i missing?

I have defined some inline functions in ns1.cpp like so:

namespace ns1 {

inline void func1(float x[3]);

}

ns1::func1(float x[3]){

//(do stuff to x)

}

Within a function far far away in class_a.cpp i consume typically like this:


include "ns1.h"

...

void class_a::func2(){

float f[3];

ns1::func1(f)

//f comes back in great shape! No runtime or compilation errors or anything.

}

My hunch is that either a) as the functions in ns1 are inline the compiler is putting the instructions for func1 within the scope of func2 and somehow not causing out of scope type errors or, b) im getting lucky and there are behaviour problems ahead of me.

EDIT: I made his question too complex. For brevity I meant "Can you create variables in one function/scope and send them out of scope to parameters of another function/different scope?". BAsed Mooing Ducks' answer below I can see how an array would work if a pointer was sent and a function altered the data the pointer was pointing to. But is it bad form to create other variable types like int, char, in one scope/function and send to another function as a parameter?

7
  • 1
    This will happen regardless of inline, so that's a red herring. inline also doesn't mean what you think it means :) Commented May 4, 2021 at 19:36
  • Also, if the function accepted a plain float instead of an array, would you expect that to work, or would you see that as the same thing? Commented May 4, 2021 at 19:39
  • @KenWayneVanderLinde 'this will happen regardless' meaning this will work everytime regardless of inline? Commented May 4, 2021 at 19:42
  • @KenWayneVanderLinde, I have been using array a lot so thought that might be relevant. I would expect ANY variable defined within func2 to fail regardless of type as it is out of scope. But it works, everytime. Commented May 4, 2021 at 19:51
  • (I'll put this in the comments since it doesn't cover the meat of the question) "But is it bad form to create other variable types like int, char, in one scope/function and send to another function as a parameter?" No, that's not bad form. The entire purpose for parameters is to be able to send stuff to functions. Commented May 4, 2021 at 23:43

1 Answer 1

2

C++ has a really stupid quirk where functions cannot take a array by value as a parameter.

inline void func1(float x[3]); //x isn't actually an array :(

Normally, all parameters are copies of the values. Except for arrays. Instead, C++ silently converts all array-value parameters to be just pointers. So it's actually:

inline void func1(float* x);

You'll even find that sizeof(f) in func2 is about 12 (an array of 3 floats, which are each ~4 bytes), and sizeof(x) in func1 is about 8 (a pointer), even though they both look like they're the same type, which really causes issues if you're not careful.

Also, since arrays can silently decay to pointers, func1 is able to modify the f variable in func2 via this pointer.

void class_a::func2(){
float f[3];
ns1::func1(f); //f decays to a pointer, so it passes a pointer to the first item.

This is super surprising even to experienced C++ developers, and why we learn to virtually never pass an array by value. Instead, pass a pointer explicitly (float* x, int size) , or an array by reference (float (&x)[3]), or a std::array (std::array<float,3> x), any of which behaves intuitively.


Interesting sidenotes:
void class_a::func2(){
float f[1024];
ns1::func1(f); //f decays to a pointer, so this also compiles :(

So definitely prefer to avoid array parameters-by-value.

Sign up to request clarification or add additional context in comments.

14 Comments

Thanks for the extra information that will be useful to know. I think my question was more basic and should have just been "Can you create variables in one scope (function) and pass as parameters to another in the C++ rulebook?" Can you?
@slexov: Pass-by-value should have been named pass-by-copy, which is clearer that it's a different variable than the caller had. However, pass-by-reference will pass a reference to the caller's variable, allowing the callee to modify it. (As observed by the float (&x)[3] sample.
Ah I think i feel some neurons connecting. So when you create a variable in one scope and 'send' it to another you are actually sending a copy of it. Array is different because you are sending a pointer rather then a copy of the array?
@slexov: Yes. By default, parameters are always copies. But you can also send references or pointers as parameters, and either will allow you to modify the variable they refer to, regardless of where it is or who owns it. Arrays are the nasty exception, because it looks like it should be a copy, but it actually passes a pointer :(
Fortunately for me that is exactly the behaviour I want!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.