Not all control paths return a value как исправить

Введение

При использовании новой версии компилятора языка MQL4 некоторые старые программы могут выдавать ошибки.

В старой версии компилятора во избежание критического завершения программ многие ошибки обрабатывались средой исполнения и не приводили к остановке работы. Например, деление на ноль или выход за пределы массива являются критическими ошибками и обычно приводят к аварийному завершению. Проявляются такие ошибки лишь в некоторых состояниях при определенных значениях переменных, однако о таких ситуациях следует знать и корректно их обрабатывать.

Новый компилятор позволяет обнаружить реальные или потенциальные источники ошибок и повысить качество кода.

В этой статье мы рассмотрим возможные ошибки, возникающие при компиляции старых программ, и методы их устранения.

  1. Ошибки компиляции
    • 1.1. Идентификатор совпадает с зарезервированным словом
    • 1.2. Специальные символы в наименованиях переменных и функций
    • 1.3. Ошибки использования оператора switch
    • 1.4. Возвращаемые значения у функций
    • 1.5. Массивы в аргументах функций
  2. Ошибки времени выполнения
    • 2.1. Выход за пределы массива (Array out of range)
    • 2.2. Деление на ноль (Zero divide)
    • 2.3. Использование 0 вместо NULL для текущего символа
    • 2.4. Строки в формате Unicodе и их использование в DLL
    • 2.5. Совместное использование файлов
    • 2.6. Особенность преобразования datetime
  3. Предупреждения компилятора
    • 3.1. Пересечения имен глобальных и локальных переменных
    • 3.2. Несоответствие типов
    • 3.3. Неиспользуемые переменные

1. Ошибки компиляции

При наличии ошибок в коде программа не может быть скомпилирована.

Для полного контроля всех ошибок рекомендуется использовать строгий режим компиляции, который устанавливается директивой:

#property strict

Этот режим значительно упрощает поиск ошибок.

1.1. Идентификатор совпадает с зарезервированным словом

Если наименование переменной или функции совпадает с одним из зарезервированных слов:

int char[];  
int char1[]; 
int char()   
{
 return(0);
}

то компилятор выводит сообщения об ошибках:

Рис.1. Ошибки "unexpected token" и "name expected"

Рис.1. Ошибки “unexpected token” и “name expected”

Для исправления данной ошибки нужно исправить имя переменной или функции.

1.2. Специальные символы в наименованиях переменных и функций

Если наименования переменных или функций содержат специальные символы ($, @, точка):

int $var1; 
int @var2; 
int var.3; 
void f@()  
{
 return;
}

то компилятор выводит сообщения об ошибках:

Рис.2. Ошибки "unknown symbol" и "semicolon expected"

Рис.2. Ошибки “unknown symbol” и “semicolon expected”

Для исправления данной ошибки нужно скорректировать имена переменных или функций.

1.3. Ошибки использования оператора switch

Старая версия компилятора позволяла использовать любые значения в выражениях и константах оператора switch:

void start()
  {
   double n=3.14;
   switch(n)
     {
      case 3.14: Print("Pi");break;
      case 2.7: Print("E");break;
     }
  }

В новом компиляторе выражения и константы оператора switch должны быть целыми числами, поэтому при использовании подобных конструкций возникают ошибки:

Рис.3. Ошибки "illegal switch expression type" и "constant expression is not integral"

Рис.3. Ошибки “illegal switch expression type” и “constant expression is not integral”

В таких случаях можно использовать явные сравнения численных значений, например:

void start()
  {
   double n=3.14;
   if(n==3.14) Print("Pi");
   else
      if(n==2.7) Print("E");
  }

1.4. Возвращаемые значений функций

Все функции, кроме void, должны возвращать значение объявленного типа. Например:

int function()
{
}

При строгом режиме компиляции (strict) возникает ошибка:

Рис.4. Ошибка "not all control paths return a value"

Рис.4. Ошибка “not all control paths return a value”

В режиме компиляции по умолчанию компилятор выводит предупреждение:

Рис.5. Предупреждение "not all control paths return a value"

Рис.5. Предупреждение “not all control paths return a value”

Если возвращаемое значение функции не соответствует объявлению:

int init()                         
  {
   return;                          
  }

то при строгом режиме компиляции возникает ошибка:

Рис.6. Ошибка "function must return a value"

Рис.6. Ошибка “function must return a value”

В режиме компиляции по умолчанию компилятор выводит предупреждение:

Рис.7. Предупреждение 'return - function must return a value"

Рис.7. Предупреждение ‘return – function must return a value”

Для исправления таких ошибок в код функции нужно добавить оператор возврата return c возвращаемым значением соответствующего типа.

1.5. Массивы в аргументах функций

Массивы в аргументах функций теперь передаются только по ссылке.

double ArrayAverage(double a[])
{
 return(0);
}

Данный код при строгом режиме компиляции (strict) приведет к ошибке:

Рис.8. Ошибка компилятора "arrays passed by reference only"

Рис.8. Ошибка компилятора “arrays passed by reference only”

В режиме компиляции по умолчанию компилятор выводит предупреждение:

Рис.9. Предупреждение компилятора "arrays passed by reference only"

Рис.9. Предупреждение компилятора “arrays passed by reference only”

Для исправления таких ошибок нужно явно указать передачу массива по ссылке, добавив префикс & перед именем массива:

double ArrayAverage(double &a[])
{
 return(0);
}

Следует отметить, что теперь константные массивы (Time[], Open[], High[], Low[], Close[], Volume[]) не могут быть переданы по ссылке. Например, вызов:

ArrayAverage(Open);

вне зависимости от режима компиляции приводит к ошибке:

Рис.10. Ошибка 'Open' - constant variable cannot be passed as reference

Рис.10. Ошибка ‘Open’ – constant variable cannot be passed as reference

Для устранения подобных ошибок нужно скопировать необходимые данные из константного массива:

   
   double OpenPrices[];
   
   ArrayCopy(OpenPrices,Open,0,0,WHOLE_ARRAY);
   
   ArrayAverage(OpenPrices);

2. Ошибки времени выполнения

Ошибки, возникающие в процессе исполнения кода программы принято называть ошибками времени выполнения (runtime errors). Такие ошибки обычно зависят от состояния программы и связаны с некорректными значениями переменных.

Например, если переменная используется в качестве индекса элементов массива, то ее отрицательные значения неизбежно приведут к выходу за пределы массива.

2.1. Выход за пределы массива (Array out of range)

Эта ошибка часто возникает в индикаторах при обращении к индикаторным буферам. Функция IndicatorCounted() возвращает количество баров, неизменившихся после последнего вызова индикатора. Значения индикаторов на уже рассчитанных ранее
барах не нуждаются в пересчете, поэтому для ускорения расчетов
достаточно обрабатывать только несколько последних баров.

Большинство индикаторов, в которых используется данный способ оптимизации вычислений, имеют вид:



int start()
  {
   
   if (Bars<100) 
     return(-1); 

   
   int counted_bars=IndicatorCounted();
   
   if(counted_bars<0) return(-1);
      
   
   int limit=Bars-counted_bars;

   
   if(counted_bars==0) 
     {
      limit--;  
      
      limit-=10;
     }
   else 
     {     
      
      limit++;
     } 
   
   for (int i=limit; i>0; i--)
   {
     Buff1[i]=0.5*(Open[i+5]+Close[i+10]) 
   }
}

Часто встречается некорректная обработка случая counted_bars==0 (начальную позицию limit нужно уменьшить на значение, равное 1 + максимальный индекс относительно переменной цикла).

Также следует помнить о том, что в момент исполнения функции start() мы можем обращаться к элементам массивов индикаторных буферов от 0 до Bars()-1. Если есть необходимость работы с массивами, которые не являются индикаторными буферами, то их размер следует увеличить при помощи функции ArrayResize() в соответствии с текущим размером индикаторных буферов. Максимальный индекс элемента для адресации также можно получить вызовом ArraySize() с одним из индикаторных буферов в качестве аргумента.

2.2. Деление на ноль (Zero divide)

Ошибка “Zero divide” возникает в случае, если при выполнении операции деления делитель оказывается равен нулю:

void OnStart()
  {

   int a=0, b=0,c;
   c=a/b;
   Print("c=",c);
  }

При выполнении данного скрипта во вкладке “Эксперты” возникает сообщение об ошибке и завершении работы программы:

Рис.11. Сообщение об ошибке "zero divide"

Рис.11. Сообщение об ошибке “zero divide”

Обычно такая ошибка возникает в случаях, когда значение делителя определяется значениями каких-либо внешних данных. Например, если анализируются параметры торговли, то величина задействованной маржи оказывается равна 0 если нет открытых ордеров. Другой пример: если анализируемые данные считываются из файла, то в случае его отсутствия нельзя гарантировать корректную работу. По этой причине желательно стараться учитывать подобные случаи и корректно их обрабатывать.

Самый простой способ – проверять делитель перед операцией деления и выводить сообщение об некорректном значении параметра:

void OnStart()
  {

   int a=0, b=0,c;
   if(b!=0) {c=a/b; Print(c);}
   else {Print("Error: b=0"); return; };
  }

В результате критической ошибки не возникает, но выводится сообщение о некорректном значении параметра и работа завершается:

Рис. 12. Сообщение о некорректном значении делителя

Рис. 12. Сообщение о некорректном значении делителя

2.3. Использование 0 вместо NULL для текущего символа

В старой версии компилятора допускалось использование 0 (нуля) в качестве аргумента в функциях, требующих указания финансового инструмента.

Например, значение технического индикатора Moving Average для текущего символа можно было запрашивать следующим образом:

AlligatorJawsBuffer[i]=iMA(0,0,13,8,MODE_SMMA,PRICE_MEDIAN,i); 

В новом компиляторе для указания текущего символа нужно явно указывать NULL:

AlligatorJawsBuffer[i]=iMA(NULL,0,13,8,MODE_SMMA,PRICE_MEDIAN,i); 

Кроме того, текущий символ и период графика можно указать при помощи функций Symbol() и Period().

AlligatorJawsBuffer[i]=iMA(Symbol(),Period(),13,8,MODE_SMMA,PRICE_MEDIAN,i); 

2.4. Строки в формате Unicodе и их использование в DLL

Строки теперь представляют собой последовательность символов Unicode.

Следует учитывать этот факт и использовать соответствующие функции Windows. Например, при использовании функций библиотеки wininet.dll вместо InternetOpenA() и InternetOpenUrlA() следует вызывать InternetOpenW() и InternetOpenUrlW().

В MQL4 изменилась внутренняя структура строк (теперь она занимает 12 байт), поэтому при передаче строк в DLL следует использовать структуру MqlString:

#pragma pack(push,1)
struct MqlString
  {
   int      size;       
   LPWSTR   buffer;     
   int      reserved;   
  };
#pragma pack(pop,1)

2.5. Совместное использование файлов

В новом MQL4 при открытии файлов необходимо явно указывать флаги FILE_SHARE_WRITE и FILE_SHARE_READ для совместного использования.

В случае их отсутствия файл будет открыт в монопольном режиме, что не позволит больше никому его открывать, пока он не будет закрыт монополистом.

Например, при работе с оффлайновыми графиками требуется явно указывать флаги совместного доступа:

   
   ExtHandle=FileOpenHistory(c_symbol+i_period+".hst",FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ);

Подробности можно найти в статье в статье “Оффлайновые графики и новый MQL4“.

2.6. Особенность преобразования datetime

Следует иметь ввиду, что преобразование типа datetime в строку теперь зависит от режима компиляции:

  datetime date=D'2014.03.05 15:46:58';
  string str="mydate="+date;

Например, попытка работы с файлами, имя которых содержит двоеточие, приведет к ошибке.

3. Предупреждения компилятора

Предупреждения компилятора носят информационный характер и не являются сообщениями об ошибках, однако они указывают на возможные источники ошибок и лучше их скорректировать.

Чистый код не должен содержать предупреждений.

3.1. Пересечения имен глобальных и локальных переменных

Если на глобальном и локальном уровнях присутствуют переменные с одинаковыми именами:

int i; 
void OnStart()
  {

   int i=0,j=0; 
   for (i=0; i<5; i++) {j+=i;}
   PrintFormat("i=%d, j=%d",i,j);
  }

то компилятор выводит предупреждение и укажет номер строки, на которой объявлена глобальная переменная:

Рис.13. Предупреждение "declaration of '%' hides global declaration at line %"

Рис.13. Предупреждение “declaration of ‘%’ hides global declaration at line %”

Для исправления таких предупреждений нужно скорректировать имена глобальных переменных.

3.2. Несоответствие типов

В новой версии компилятора введена операция приведения типов.

#property strict
void OnStart()
  {
   double a=7;
   float b=a;
   int c=b;
   string str=c;
   Print(c);
  }

В строгом режиме компиляции при несоответствии типов компилятор выводит предупреждения:

Рис.14. Предупреждения "possible loss of data due to type conversion" и "implicit conversion from 'number' to 'string'

Рис.14. Предупреждения “possible loss of data due to type conversion” и “implicit conversion from ‘number’ to ‘string’

В данном примере компилятор предупреждает о возможной потере точности при присвоении различных типов данных и неявном преобразовании типа int в string.

Для исправления нужно использовать явное приведение типов:

#property strict
void OnStart()
  {
   double a=7;
   float b=(float)a;
   int c=(int)b;
   string str=(string)c;
   Print(c);
  }

3.3. Неиспользуемые переменные

Наличие переменных, которые не используются в коде программы (лишние сущности) не является хорошим тоном.

void OnStart()
  {
   int i,j=10,k,l,m,n2=1;
   for(i=0; i<5; i++) {j+=i;}
  }

Сообщения о таких переменных выводятся вне зависимости от режима компиляции:

Рис.15. Предупреждения "variable '%' not used'

Рис.15. Предупреждения “variable ‘%’ not used’

Для исправления нужно убрать неиспользуемые переменные из кода программы.

Выводы

В статье рассмотрены типичные проблемы, с которыми могут столкнуться программисты при компиляции старых программ, содержащих ошибки.

Во всех случаях при отладке программ рекомендуется использовать строгий режим компиляции.

Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.

Any advice?

The compiler is giving you the best advice. Not all the control paths in your function contain a return statement, and your function is supposed to return a value.

If an exception is thrown and control is transferred to a catch handler, that handler will print something to cerr and then flow off the end of your function without actually returning anything.

This is Undefined Behavior. Per Paragraph 6.6.3/2 of the C++11 Standard:

[..] Flowing off the end of a function is equivalent to a return with no value; this results in undefined
behavior in a value-returning function
.

For default-constructible values, you could fix this by adding a return T() statement right before the end of your function:

template<typename T>
T Stack<T>::Pop()
{
    try
    {
        // ...
    }
    catch (OutOfBoundsException&)
    {
        // ...
    }
    catch (...)
    {
        // ...
    }

    return T();
//  ^^^^^^^^^^^
}

A more reasonable approach is, however, to not have Pop() swallow the exception, but rather re-throw it. Pop() does not have strategic-level information on how to recover from an error occurred in this context:

template<typename T>
T Stack<T>::Pop()
{
    try
    {
        // ...
    }
    catch (OutOfBoundsException&)
    {
        // ...
        throw; // <== Re-throw after printing the diagnostic
    }
    catch (...)
    {
        // ...
        throw; // <== Re-throw after printing the diagnostic
    }
}

Even better would be if the responsibility for logging an error message did not belong to Pop() at all, since Pop() is likely supposed to be re-used by code with different requirements in this sense (some may not want to log anything, some may want to log messages to a file, some may want to log messages in a different language, and so on).

So a more reasonable version of your function would actually be:

template<typename T>
T Stack<T>::Pop()                
{
    if (m_index<0) throw OutOfBoundsException(m_index);
    --m_index;
    return(m_array[m_index]);
}

In general, you should try (no pun intended) to avoid try/catch blocks unless you have to:

  • Translate an exception
  • Recover from the error (but you need strategic knowledge for doing this)

If this not your task (as is the case for a function like Pop() above), in most situations the best thing to do is to not handle exceptions at all and let them propagate up the call stack.

To quote Dave Abrahams:

Often the best way to deal with exceptions is to not handle them at all. If you can let them pass through your code and allow destructors to handle cleanup, your code will be cleaner.

To avoid leaking memory, resources, or in general responsibilities, write code that is exception-safe by using adequate RAII wrappers. Excellent guidelines in this sense are given in this two-part talk by Jon Kalb.

In particular, avoid writing catch (...) handlers: exceptions were invented to prevent programmers from ignoring errors, and swallowing them all in a universal handler without re-throwing them is the best way to ignore them.


NOTE:

Notice, that your implementation of Pop() is a bit problematic: what happens if the copy constructor or move constructor of T throws when returning the element back to the caller, after you already modified the stack pointer?

This is the reason why the C++ Standard Library defines two separate functions pop() and top(): because it allows to offer strong guarantee, i.e. to give transactional semantics to your pop() operation – either the element is removed without exceptions being thrown, or the function had no effect at all.

How to fix not all code paths return a valueWhen you run a set of instructions on your program and it displays not all code paths return a value, it’s an error message. It is caused because the compiler has hit the end of the function without the return statement. The return statement ends the execution of the function and returns a value to the calling function.

If you want to know why you keep receiving the error message, our coding experts are here to help you out!

Contents

  • Why Is Your System Displaying Not All Code Paths Return a Value?
    • – What Happens if There Is No Return Statement in Your Code?
  • How To Solve This Error
    • – Example 1: Fixing the Error While Using C# Program
    • – Example 2: Not All Code Paths Return a Value For C#
    • – Example 3: Fixing the Error While in JavaScript
    • – Example 4: Fixing the Error While Using Typescript
    • – Example 5: Not All Code Paths Return a Value in Lambda Expression
  • FAQs
    • – Which One Is Better, Using”If-else” or “Return”?
    • – What Is the Use of Return Value in Java?
  • Conclusion

Why Is Your System Displaying Not All Code Paths Return a Value?

Your system is displaying that not all code paths return a value error because there should be at least one route that returns a value to the caller but, in this case, there is no route through your function that returns a value. The error message means that the compiler found a way to hit the end of the function without a return statement that tells it what it’s supposed to return.

Another cause of the warning message appearing can be caused if there is no return statement in your code.

– What Happens if There Is No Return Statement in Your Code?

If no return statement appears in a function definition, control automatically returns to the calling function after the last statement of the called function is executed. In this case, the return value of the called function is undefined. If the function has a return type other than void, it’s a serious bug, and the compiler displays an error message.

We recommend that you always use a plain return statement to make your intent clear.

How To Solve This Error

The warning message is common for almost all programming languages such as Lambda, JavaScript, jQuery, C#, PHP, PowerShell 5, and so on.

So, to fully cover the error, we will consider some examples of this error for a couple of programming languages.

– Example 1: Fixing the Error While Using C# Program

Here is an example of a code path that does not return a value resulting in an error when using c# to program:

public bool FindItem(GameObject item)
{
for (int i = 0; i < MyInventory.Length; i++)
{
if (MyInventory[i] == item)
{
//we found the item
return true;
}
//if item not found
return false;
}
}

Result:

Assets/Script/Items/InventoryScript.cs(35,17):error CS0161: `InventoryScript.FindItem(UnityEngine.GameObject)’: not all code paths return a value eslint

Solution:

public bool FindItem(GameObject item) {
return System.Array.IndexOf(MyInventory, item) >= 0;
}

Result:

Assets/Script/Items/InventoryScript.cs(35,17): error CS0161: `InventoryScript.FindItem(UnityEngine.GameObject)’: not all code paths return a value

Problem: The error here is that for loop, we set I = 0. In this case, the test failed because I < My inventory. length which isn’t valid as zero is not less than zero. Since the test failed, the function exits the for loop immediately without checking the following code and not returning true or false. And here we see the error message because we haven’t encountered a return statement.

To fix this problem, we will need to move the return false statement outside the loop to the very end of the function. The loop will check whether the item is in MyInventory [0], and if not, it will always return false before it gets a chance to check MyInventory [1]. We will want to return true if and only if the program ran through the whole array and didn’t find the item, not immediately after a single mismatch.

We recommend you use this solution:

Solution:

public bool FindItem(GameObject item) {
return System.Array.IndexOf(MyInventory, item) >= 0;
}

– Example 2: Not All Code Paths Return a Value For C#

Here is another example if you receive this error message when using c# to program.

We will run a program on the bool value function to see the error.

class Program
{
static void Main(string[] args)
{
bool myChoice = true;
while (myChoice)
{
myChoice = ChoiceGame();
}
}
private static bool ChoiceGame()
{
char Choice;
string Con = “y”;
Console.WriteLine(“What is the command keyword to exit a loop in C#?”);
Console.WriteLine(“a. Quit”);
Console.WriteLine(“b. Continue”);
Console.WriteLine(“c. break”);
Console.WriteLine(“d. exit”);
while (Con == “y”)
{
Console.WriteLine(“Enter Your Choice:”);
Choice = (char)Console.Read();
if (Choice == ‘c’)
{
Console.WriteLine(“Congratulations”);
return false;
}
else if (Choice == ‘a’ || Choice == ‘b’ || Choice == ‘d’)
{
Console.WriteLine(“Incorrect”);
Console.WriteLine(“Again?press y to continue”);
Con = Console.ReadLine().ToString();
return true; }
else
{
Console.WriteLine(“Invalid choice”);
return false;
}
}
}. (solution here)
}

Result: not all code paths return a value c#

Solution: Here in the function, we are returning value for if and else if and then for else. In the if-else statement we selected “c”, “a”, “b”, “d”. There is a logical error here – the compiler doesn’t understand that we will always be in a while loop, and this is why it is showing an error.

After the else returns false, the function should return the while loop false.

– Example 3: Fixing the Error While in JavaScript

If you receive the error message while using JavaScript, it means that in your program there is an instance where your return statement is not returning a value to the calling function.

Let’s consider an example where the set of instructions leads to an error and the possible solution.

document.getElementById(‘search_field’).onkeypress = function(e) {
if (!e) e = window.event;
var keyCode = e.keyCode || e.which;
if (keyCode == ’13’) {
window.location.href = ‘/search/?s=’ + $(‘#search_field’).val();
return false;
}
};

We know that the last bracket will show you an error if you try it, indicating that there is a problem with the code.

To solve the error, try returning the if statement true.

Possible solution:

document.getElementById(‘search_field’).onkeypress = function(e) {
if (!e) {
e = window.event;
}
var keyCode = e.keyCode || e.which;
if (keyCode == ’13’) {
window.location.href = ‘/search/?s=’ + $(‘#search_field’).val();
return false;
}
return true;
};

– Example 4: Fixing the Error While Using Typescript

Let’s consider another example – a Typescript code path that does not return a value, resulting in an error.

public MakeMove(board: Board): boolean {
var pos = this.clickedPosition;
this.clickedPosition = null;
if (null === pos) {
return false;
}
if (this.id === pos.player) {
if (board.GetStones(pos) > 0) {
var finalDrop = board.Sow(pos);
board.Capture(pos.player, finalDrop);
} else {
alert(“Select a house with at least 1 stone!”);
}
} else {
alert(“Select a house from your side!”);
}
}

The mystery here is that, if you remove all the return statements, you will get the expected error.

Result: not all code paths return a value.ts(7030) typescript

– Example 5: Not All Code Paths Return a Value in Lambda Expression

Here is an example of a code path that does not return a value resulting in an error when using Lambda. It means your return statement is not working.

Let’s call a function CountPixels

Task<int> task1 = newTask<int> (() => {CountPixels (croppedBitmap, colour angle.fromArgb (255, 255, 255, 255));});

In the end, we will get an error because we didn’t return CountPixels.

Also, when using PowerShell 5, you can receive an error message, not all code paths return value within method powershell. Now you know what this means.

FAQs

– Which One Is Better, Using”If-else” or “Return”?

They are equally efficient, but the return is usually considered to give better readability, especially when used to eliminate several nested conditions.

Note:

The return should be the last line in the function which returns either a specified value or the last variable assignment in the function. The if-else is meant to conditionally execute code if your test premise is false.

if /* some condition is not met */
return
if /* another requirement is not met */
return
if /* yet another requirement fails */
return
/* now we know it’s OK to proceed */
/*
the “real” work of the procedure begins here
*/

– What Is the Use of Return Value in Java?

The return is used in Javascript, not as an identifier but to exit from a method with or without a value.

Let’s consider an example you can try by yourself. A method with a return value:

public class Main {
static int myMethod(int x) {
return 5 + x;
}
public static void main(String[] args) {
System.out.println(myMethod(3));
}
}
// Outputs 8 (5 + 3)

Conclusion

Now that you have read our article, you won’t find it difficult to solve code path errors again in your function because our coding experts have shown you possible problems and their solutions. Let’s see some of the points we mentioned in the article:

  • The error message is caused whenever the return statement is unable to return a value to the calling function
  • The set of instructions in our programming is known as code path
  • The return statement simply means an exit point from a function
  • The error message can be seen in programming languages such as JavaScript, jQuery, PHP, Dartz, and so on.
  • A function continues to run infinitely unless it is returned

Not all code paths return a valueThe function of the return statement cannot be underrated as it gives the code better readability.

  • Author
  • Recent Posts

Position is Everything

Your Go-To Resource for Learn & Build: CSS,JavaScript,HTML,PHP,C++ and MYSQL. Meet The Team

Position is Everything

150333

3 / 3 / 0

Регистрация: 18.10.2013

Сообщений: 107

1

01.12.2013, 15:44. Показов 3066. Ответов 2

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <math.h>
 
using namespace std;
 
float max (float a, float b, float c)
{
    if (a >= b && a >= c)
        return a;
    else if (b >= a && b >= c)
        return b;
    else if (c >= a && c >= b)
        return c;
  
        
}
 
float min (float a, float b, float c)
{
    if (a <= b && a <= c)
        return a;
    else if (b <= a && b <= c)
        return b;
    else if (c <= a && c <= b)
        return c;
   
       }
 
 
bool main()
{
    float a, b, c;
    float y;
 
    std::cout << "Enter a, b, c: ";
    std::cin >> a >> b >> c;
 
    y = max (a, b, c) * min (a, b, c);
 
    std::cout << "Max * Min = " << y << std::endl;
    return 0;
}

Выдает два предупреждения:
warning C4715: ‘min’ : not all control paths return a value
warning C4715: ‘max’ : not all control paths return a value
Что не так? Как исправить ?



0



5496 / 4891 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

01.12.2013, 21:17

2

Если не выполнится ни одно из условий, то что вернётся из функций? Но это только предупреждение компилятора. Может всё и правильно работать.



0



43 / 43 / 15

Регистрация: 15.12.2012

Сообщений: 88

01.12.2013, 21:21

3

Цитата
Сообщение от 150333
Посмотреть сообщение

Выдает два предупреждения:
warning C4715: ‘min’ : not all control paths return a value
warning C4715: ‘max’ : not all control paths return a value
Что не так? Как исправить ?

Перевод таков:
в функции ‘min/max’ значение возвращается не во всех случаях



0



  • Forum
  • Beginners
  • Not all control paths return a value?

Not all control paths return a value?

I’m trying to create a code for password verification for a class. I thought I had it working but for some reason every time I input a seemingly correct password, it says it must have one lowercase letter. The only error I can find is “not all control paths return a value.” Any help please?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
  #include <iostream>
#include <cstring>
#include <cctype>
using namespace std;

bool lengthTest(char []);
bool upTest(char []);
bool lowTest(char []);
bool numTest(char []);

int main()
{
	char password[20];

	// Explain password criteria and prompt user for password.
	cout << "The password must have:n" <<
			"      at least 6 characters,n" <<
			"      at least one uppercase character,n" <<
			"      at least one lowercase character,n" <<
			"      at least one numeric digit.n" <<
			"Enter a password:n";
	cin.getline(password,20);

	// Verify password.
	if (lengthTest(password))
	if (upTest(password))
	if (lowTest(password))
	if (numTest(password))
		cout << "The password is valid.n";
	else
		cout << "The password is invalid.n";

	return 0;

}

// *******************************************
//         Verifies password length.
// *******************************************
bool lengthTest(char custPass[])
{
	int length;
	length = strlen(custPass);
	
	if (length >= 6)
		return true;

	else
		cout << "The password must have a minimum of 6 characters.n";
		return false;
}
// *******************************************
//         Verifies uppercase letter.
// *******************************************
bool upTest(char custPass[])
{	
	for (int i = 0; i < 20; i++)
		{	
			if (isupper(custPass[i]))		
			return true;

			else
			cout << "Must have at least one uppercase letter.n";
			return false;
		}
}
// *******************************************
//         Verifies lowercase letter.
// *******************************************
bool lowTest(char custPass[])
{	
	for (int i = 0; i < 20; i++)
		{	
			if (islower(custPass[i]))		
			return true;

			else
			cout << "Must have at least one lowercase letter.n";
			return false;
		}
}
// *******************************************
//             Verifies digit.
// *******************************************
bool numTest(char custPass[])
{	
	for (int i = 0; i < 20; i++)
		{	
			if (isdigit(custPass[i]))		
			return true;

			else
			cout << "Must have at least one digit.n";
			return false;
		}
}

Could you copy and paste your errors?

Also, you should probably use { } for all of your if statements so they are easier to read.

warning C4715: ‘upTest’ : not all control paths return a value
warning C4715: ‘lowTest’ : not all control paths return a value
warning C4715: ‘numTest’ : not all control paths return a value

It says the build succeeded but it isn’t working like how it should.

And by your suggestion, do you mean around the first collection of ifs?

Lets start with:

1
2
3
4
5
6
7
8
9
10
11
12
bool upTest(char custPass[])
{	
	for (int i = 0; i < 20; i++)
		{	
			if (isupper(custPass[i]))		
			return true;

			else
			cout << "Must have at least one uppercase letter.n";
			return false;
		}
}

I add braces to make it more clear what you are doing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool upTest(char custPass[])
{	
  for (int i = 0; i < 20; i++)
  {
    if (isupper(custPass[i]))
    {
      return true;
    }
    else
    {
      cout << "Must have at least one uppercase letter.n";
    }

    return false;
  }
}

But why have a loop at all, since there will be a return on first iteration:

1
2
3
4
5
6
7
8
9
10
11
12
13
bool upTest(char custPass[])
{
  if (isupper(custPass[0]))
  {
    return true;
  }
  else
  {
    cout << "Must have at least one uppercase letter.n";
  }

  return false;
}

Is that really what you want your function to do?

Last edited on

Topic archived. No new replies allowed.

Добавить комментарий