0

How to prevent coder from returning local variable as reference?

Example 1

I sometimes make a mistake like this :-

int& getStaticCache(){
    int cache = 0; return cache;  //<--- dangling pointer
}

The correct code is :-

int& getStaticCache(){
    static int cache = 0; return cache;  //OK
}

Example 2

Another case is :-

std::vector<Protocol>& getInternalController(){ .... some code .... }
std::vector<Protocol>& getController(){
    std::vector<Protocol> controller=getInternalController_();
    return controller;  //<--- dangling pointer
}

The correct code is :-

std::vector<Protocol>& getController(){
    return getInternalController_();  //<--- OK
}

It may be just me, because I am not skillful in C++ enough.
However, these occur to me once every 3 months, especially in bad time.

Question: What programming technique / design pattern / software engineering jargon / C++ magic / tool / plugin that can help me reduce the rate of this specific type of my own mistake?

I am using Visual Studio.

javaLover
  • 6,347
  • 2
  • 22
  • 67
  • "The correct code is..." Beware of wishful thinking. – n. m. could be an AI Mar 13 '17 at 08:37
  • The "correct" solution to all your cases would be to return a *value* instead of a reference. Especially when returning a single `int` it often (like in your case) makes no sense to return references. – Some programmer dude Mar 13 '17 at 08:39
  • @n.m. I am an optimistic person. Is it also a root of my problem? *Hopefully*, not! – javaLover Mar 13 '17 at 08:39
  • @Some programmer dude Sometimes I need it. ...... In first example: it is a field in a template type - I have to force the variable to be initialized before used. The only way is to put it in as a static variable inside function. http://stackoverflow.com/q/10011039/3577745 ..... In the second example, it is for performance reason. – javaLover Mar 13 '17 at 08:40
  • Regarding the "performance reasons", modern compilers (and even some pretty old) are *very* good at return-value optimizations and eliding copying. And since the C++11 standard data could be *moved* instead of copied, which for vectors means you can simply return a vector by value and it will be moved instead of copied. – Some programmer dude Mar 13 '17 at 08:44
  • 1
    `static int cache = 0; return cache;` is the root cause of a bunch of *other* problems. – n. m. could be an AI Mar 13 '17 at 08:50

1 Answers1

1

Start with not ignoring warnings the compiler gives you.

c:\CODE>type bad.cpp
int& foo()
{
    int a = 42;
    return a;
}

c:\CODE>cl /c bad.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

bad.cpp
bad.cpp(4) : warning C4172: returning address of local variable or temporary

c:\CODE>

This is a "severe" (level 1) warning. even the "least serious" (level 4 in case of VS) warnings can be deadly. Shoot for zero warnings at thhe highest (least serious) level. You may not be able to eliminate all of them by changing your code, but you have to understand why they are given. Disable each instance on a case-by-case basis if there is no other way to silence them and you are absolutely sure they are harmless.

Why do so? Simple: if you have a bunch of totally harmless warnings popping up each time you compile your code, you stop paying attention and the next serious warning you introduce goes unnoticed.

Making your compiler treat warnings as errors is very useful. I always enable this setting in my projects as a matter of policy.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
  • I notices that it is a compiler warning level 1. Does it mean "most serious" or "least serious"? Oh, I see it is most serious. Thank. I should not turn off the warning. XD – javaLover Mar 13 '17 at 08:52
  • @javaLover even the "least serious" warnings can be deadly. Shoot for zero warnings at thhe highest (least serious) level. You may not be able to eliminate all of them by changing your code, but you have to understand why they are given. Disable each instance on a case-by-case basis. – n. m. could be an AI Mar 13 '17 at 08:58
  • Yes, sir n.m. I will take your advice gracefully. – javaLover Mar 13 '17 at 09:00
  • Enabled your compiler's "treat warnings as errors" option so that warnings can't get lost. If you have a real false positive warning, use annotations to suppress it. – Sebastian Redl Mar 13 '17 at 09:09
  • @Sebastian Redl Do you mean "suppress" like [#pragma warning( push ) #pragma warning( disable : 4101)](http://stackoverflow.com/a/7159392/3577745)? – javaLover Mar 13 '17 at 09:14
  • @SebastianRedl yeah, but it looks like this is turning into a general treatise on warnings. Better stop now... – n. m. could be an AI Mar 13 '17 at 09:16