Variable not used как исправить

Введение

При использовании новой версии компилятора языка 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. Полная или частичная перепечатка запрещена.

How to avoid java warning which says

The value of the local variable is not used

for the variable which is declared as private?

Sabir Khan's user avatar

Sabir Khan

9,7167 gold badges41 silver badges97 bronze badges

asked Jan 21, 2016 at 6:54

Yathish Kumar B's user avatar

4

You have multiple choices:

  1. Remove the field.
    It is unused, so it shouldn’t be there.
  2. Comment out the field, e.g. using // TODO
    Good for temporary hiding of warning until you write code using field.
  3. Suppress the warning using @SuppressWarnings("unused").
  4. Disable the warning in IDE settings. For Eclipse, that would be in
    • Window > Preferences
    • Java > Compiler > Error/Warnings
    • Unnecessary code > Unused private member
    • Select option Ignore

For #3 and #4, though, although you can, why would you want to?

answered Jan 21, 2016 at 7:15

Andreas's user avatar

AndreasAndreas

154k11 gold badges146 silver badges241 bronze badges

Since it is not used and does not contain any code you are interested in, you can delete it.

answered Jan 21, 2016 at 6:59

Admx's user avatar

AdmxAdmx

1051 silver badge9 bronze badges

It is saying because the value of the variable or variable is not used within the program. So to remove this warning you can simply delete this variable because you are not using it anywhere .Or use this variable at some point in your code

answered Jan 21, 2016 at 7:11

Harinder mourya's user avatar

Actually, in some cases it’s not that easy. Here’s an example of why it’s not as easy as just commenting out the code. Sure this is a comment, but I don’t have rep of 50 to comment and the comment block is lame anyway. So sue me. This does not work by the way, but comments are lame here.

try {
    // so, rather than a wait, we check for exit value
    // and if that tosses an exception, the process is
    // still running. Ooooooookkkkkaaaaaayyyyyy No Problem
    int exitValue = pShowProcess.exitValue();
    // guess we don't do this to get rid of the not referened warning
    //(void)exitValue;
    // we don't care what the exit value was
    exitValue = 0;
    // but if we get here, then the show stopped, so
    // if we stop it now, it won't need to wait, it will be fine
    // we think.
    endShow();
} catch (Exception ex) {
    // Process is still running. So just keep going until
    // mouse clicks or something else stops the show
}

Paolo's user avatar

Paolo

19.7k21 gold badges71 silver badges113 bronze badges

answered Apr 26, 2020 at 15:27

windyplayer's user avatar

In this tutorial, we will walk through some examples of avoiding error «declared and not used» in Golang. If a variable is defined in the Go programming language but not used in the code, the compiler will display the error «declared and not used» We must eliminate any unnecessary packages or variables from the code in accordance with best practices for programming. Memory, compilation, and execution time will be saved.

You can avoid removing those unnecessary variables or packages by using the blank identifier (_).

Take a look at the examples below:

Example 1: Error — «imported and not used»

Here we have a sample go code:

package main

import (
	"fmt"
	"encoding/json"
)

func main() {
	name := "GoLinuxCloud"
	age := 1
	fmt.Println("My name is:", name, "and my age is: ", age)
}

In the above code, two packages <span class="w3-codespan">fmt</span> and encoding/json are imported but encoding/jsonwas not used. So the following error will return:

# command-line-arguments
.milestone8.go:5:2: imported and not used: "encoding/json"

Fix imported and not used

We ca use a blank identifier (_) before the package name that will not be used as following code:

package main

import (
	"fmt"
	_ "encoding/json"
)

func main() {
	name := "GoLinuxCloud"
	age := 1
	fmt.Println("My name is:", name, "and my age is:", age)
}

Output:

My name is: GoLinuxCloud and my age is: 1

ALSO READ: How Golang Garbage Collector Works? [Tutorial]

Example 2: Error — «declared and not used»

Here we have another go code:

package main

import (
	"fmt"
)

func main() {
	page := "GolinuCloud"
	author := "Anonymous Author"

	fmt.Println("Name is:", page)
}

In the above code, two variables page and author are declared but author was not used. So the following error will return.

# command-line-arguments
.milestone8.go:9:2: author declared but not used

Fix declared but not used

To avoid this error we can assign the variable to a blank identifier (_) as the following code:

package main

import (
	"fmt"
)

func main() {
	page := "GolinuCloud"
	author := "Anonymous Author"

	fmt.Println("Page is:", page)
	_ = author
}

Output:

Page is: GolinuCloud

Example 3: Variable declared and used but still getting “declared but not used”

In the below example, the variable is used but the program still arise declared but not used error:

package main

import "fmt"

func main(){
    var boolStr string

    if false {
        boolStr := "False"
    }else{
        boolStr := "True"
    }

    fmt.Println(boolStr) // variable used
}

Because the variable boolStris being re-declared in the if-else block of the code, it returns the error. Any variables declared using := are local in the go programming language, meaning they can only be utilized inside the specific block or function. The code fails because the variable is not used in the specific if-else block range. To solve this problem, you just need to assign new values to the global variable boolStr instead of declaring them again, as shown below:

package main

import "fmt"

func main(){
    var boolStr string // declared global variable

    if false {
        boolStr = "False" // asign value, not declare again
    }else{
        boolStr = "True"
    }

    fmt.Println(boolStr) // variable used
}

Output:

True

ALSO READ: When does the init() function run in GO? [SOLVED]

Summary

In this article, I have provided some example of how to eliminate declare but not used error. The presence of an unused variable may indicate a bug, while unused imports just slow down compilation. Accumulate enough unused imports in your code tree and things can get very slow. For these reasons, Go allows neither.

To avoid these compilation errors I recommend using Visual Studio Code for GO IDE which will warn you about these errors even before you compile and run your code.

References

https://go.dev/doc/effective_go#blank

Didn’t find what you were looking for? Perform a quick search across GoLinuxCloud

C++ is not Java. You can’t just assign structs like that — it copies them (if anything).

Boid b = boids[I]; // <<<<<<<<<<<<< this line!
b.start_animate_time = 456;

Instead just access the array slice directly:

boids[i].start_animate_time = 456;

And later on as well:

Serial.println(boids[i].start_animate_time);

Basically, you create a «Boid» variable called «b», copy the content of boids[i] to it, set a value in that variable, and then throw it away. Hence the «not used». If you want to reference a specific array slice as a separate variable either get a pointer to it:

Boid *b = &boids[i];
b->start_animate_time = 456;

Or use a reference:

Boid &b = boids[i];
b.start_animate_time = 456;

Of the two I prefer using a pointer, but I come from a C background and understand pointers, but it took me many years of trial and error to get to that point…

In this tutorial you are going to know the solution for the declared but not used error in golang / go

Probability 1 : Variable declared and not used anywhere

It means that you have declared a variable in the code but did not used it anywhere. This makes the code crash because go wants you to write clean code which is easy to understand and use every variable you declare.

Ignoring unused variable

If you want to ignore this error you can comment that declaration part of the code or use a blank identifier _ as shown below.

        package main

func main(){
    str := "bugz"
    _ = str // using blank identifier
}
      

Probability 2 : Variable declared and used yet the code crashes

        package main

import "fmt"

func main(){

    var str string

    if false {
        str := "bugz"
    }else{
        str := "new bugz"
    }

    fmt.Println(str) // variable used
}
      

In the code above, the variable str is used yet the code crashes with the same error.

It returnes the error because, in the if-else block of the code, the variable str is being re-declared. In go, any variables declared in the if-else blocks are local which means that the variables can be used only in the block range ( in the if-else block ).

As in the block range the variable is not being used, the code crashes.

Solution

As you are re-declaring & not using the str variables , the code is crashing. To solve this problem, you just need to assign new values to the global variable str instead of declaring them again, as shown below.

        var str string // global variable

if false {
    str = "bugz" // assigning "bugz" to str
}else{
    str = "new bugz" // assigning "new bugz" to str
}
      

Declaring vs Assigning

        str := "bugz" // declaring. ":="

str = "bugz" // assigning. "="
      

Thank you for reading, happy coding ✌🏾

Понравилась статья? Поделить с друзьями:
  • Как найти время встречи зная скорость сближения
  • Как найти амплитуду колебаний звуковой волны
  • Не получился яблочный уксус как исправить
  • Assassins creed brotherhood как найти аконит
  • Как найти площадь дома буквой г