Error 088 cannot return a value from a void function

Ошибка при компиляции - отправлено в Left 4 Dead 2: Выдает ошибку при компиляции:error 161: brackets after variable name indicate a fixed-size array, but a dynamic size was given - did you mean to use new int[size] syntax?вот код: stock void BfReadSBitLong(Handle bf,int numBits) { int bits[numBits], ret, i; //вот здесь ошибка for (i = 0; i < numBits; i++) { bits[i] = BfReadBool(bf); } ret = bits[numBits-1] ? -1 : 0; for (i = numB...
stock bool IsAdmin(int client)
{
	return (GetUserFlagBits(client) & ADMFLAG_ROOT) != 0;
}

Вот пример проверки, является ли клиент админом.
Разве тут bool не возвращает функцию?

Как это работает.
Есть функция (в данном случае IsAdmin). Она должна нам вернуть bool раз уж так решили при её объявлении (возвращаемый тип пишется перед названием функции).
Это значит, мы должны в конце выполнения функции вернуть значение с тем же типом. То есть после «return» должно идти значение с типом bool.

Функции с типом bool отвечают на вопрос «Да» или «Нет»
Что есть bool. Это либо true («Да»), либо false(«Нет»).
Частенько пишут сначала проверку if, а по её результатам «return true» или «return false»
Например:

stock bool IsAdmin(int client)
{
    if ((GetUserFlagBits(client) & ADMFLAG_ROOT) != 0)
        return true;
    else
        return false;
}

Но ленивые программисты не хотят писать лишние строки для такой рутины.
Зачем писать лишние if-else, если GetUserFlagBits(client) & ADMFLAG_ROOT) != 0 и так нам вернёт в качестве результата true или false (Оно или 0 или нет)
Поэтому пример выше сокращается до уже известного:

stock bool IsAdmin(int client)
{
    return (GetUserFlagBits(client) & ADMFLAG_ROOT) != 0;
}

Но что если пойти дальше?

Если досконально рассматривать выражение (GetUserFlagBits(client) & ADMFLAG_ROOT) != 0, то что можно заметить?

Что из себя в принципе представляет GetUserFlagBits(client) & ADMFLAG_ROOT?

Там имеется оператор «Побитовое И» (» & «). Он вернёт результат побитового умножения цепочки битов. Прочитали? Забудьте и просто посмотрите, как это работает.

Возьмём два числа. Например, 12 и 5. Это их десятичный вид.

В двоичном виде они выглядят так: 1100 и 101
Мы вправе дописывать нули перед числом (5 и 05 — одно и тоже). С двоичным числами это тоже работает.
Чтобы было легче в будущем понимать магию, сделаем так, чтобы количество цифр в числах было одинаковое: 1100 и 0101

И что теперь? А дальше магия.

Запишем их в столбик

1100

0101

А теперь каждый столбик отдельно перемножим (буквально).
 

    1        1        0        0

 x         x        x         x

    0        1        0        1

    —————————

    0        1        0        0

Получилось число 0100. Вернём обратно в десятичный вид и получим… Число 4.

Но это лишь проекция логической операции «побитового И» на привычную нам математическую операцию умножения. Заумно? Согласен.
Давайте по-простому. Уберём всю эту математику и получим:
«Если хоть где-то 0, то и результат 0, иначе 1». Проще и лаконичнее.

И как это вообще связано с функциями и bool’ами?

Сейчас покажу.

GetUserFlagBits(client) & ADMFLAG_ROOT делает всё абсолютно то же самое. Просто ADMFLAG_ROOT — заготовленное число (константа), а GetUserFlagBits(client) — число, которое вернёт нам функция GetUserFlagBits (слово Bits в её названии намекает на «двоичное» назначение данного числа)

ADMFLAG_ROOT — число известное. Оно записано в коде SourceMod и равно 1<<14 (это побитовое смещение, но мы — люди простые, и можем это прочитать как «дописать 14 нулей перед двоичным значением числа 1»). Выглядит это примерно так 0100 0000 0000 0000 (часто запись идёт четверками).
GetUserFlagBits вернет нам «Побитовое ИЛИ» (» | «) всех флагов игрока. (замените умножение на сложение, а там если хоть где-то 1, то и результат 1, иначе 0 (1100+0101=1101).

Если у игрока прав нет, то GetUserFlagBits вернёт 0. А как мы теперь знаем, если где-то 0, то и результат 0.

Если у игрока права есть, например ADMFLAG_BAN и ADMFLAG_KICK, то функция нам вернёт (1<<2) | (1<<3) или 0100 | 1000. Что в итоге будет 1100.

А дальше это маленькое 1100 побитово перемножается с огромным 0100 0000 0000 0000.
И что получится?

0. Получится ноль. Но что это значит для нас? Это значит, что игрок не принадлежит к ADMFLAG_ROOT, то есть он не Root админ.

А если бы набор был бы, например, из ADMFLAG_BAN, ADMFLAG_KICK и ADMFLAG_ROOT?

(ADMFLAG_BAN | ADMFLAG_KICK | ADMFLAG_ROOT) & ADMFLAG_ROOT = …

… = ADMFLAG_ROOT

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

Ну, а что же мы по итогу, то имеем?

GetUserFlagBits(client) & ADMFLAG_ROOT вернёт нам либо 0, либо число, равное ADMFLAG_ROOT

Признаюсь честно, такой записи я никогда не встречал, но она будет работать, как задумано)

stock bool IsAdmin(int client)
{
    return GetUserFlagBits(client) & ADMFLAG_ROOT == ADMFLAG_ROOT;
}

Но что если, нам нужно указать принадлежность не к конкретному админу к одному из определенного списка. Далеко уходить не будем: ADMFLAG_BAN, ADMFLAG_KICK и ADMFLAG_ROOT.

Сделать так?

//Ради Бога, не используйте это (как и всё предыдущее)
stock bool IsAdmin(int client)
{
    return GetUserFlagBits(client) & (ADMFLAG_BAN|ADMFLAG_KICK|ADMFLAG_ROOT) == (ADMFLAG_BAN|ADMFLAG_KICK|ADMFLAG_ROOT);
}

И… Это работать не будет (в отличие от всего предыдущего), так как никто не гарантирует, что у игрока будут сразу 3 этих флага. Но по итогу это всё равно будет каким-то числом, отличным от 0, если хоть один из этих флагов есть.

Вы всё ещё здесь? Чудо. Не меньше. Тем не менее…

Вернёмся в самое начало.
Функции с типом bool отвечают на вопрос «Да» или «Нет»
Мы поняли, что если у игрока нет нужных флагов, то GetUserFlagBits(client) & (Нужный_Флаг1|Нужный_Флаг2) вернёт 0.
И поняли, что если нужный флаг есть, то вернётся не 0.
Соединяем эти 3 факта и получим:

stock bool IsAdmin(int client)
{
    return (GetUserFlagBits(client) & ADMFLAG_ROOT) != 0;
}

Вопрос о том, как вообще получилось это выражение, не поднимался, но вот на него ответ)

Но есть ещё одна хитрость. Преобразование типов.

В данном случае у нас есть целое число, но нужно булево значение.
true и false, часто интерпретируют как целые числа «1» и «0» (выше можно понять почему). 
А вот наоборот «0» — это false, а любое другое число — это true.
Но как сказать компилятору, что нужно преобразовать тип и значение?
Есть 2 способа. Обернуть нужное значение в конструкцию view_as<bool>(GetUserFlagBits(client) & ADMFLAG_ROOT), что считается явным (explicit) преобразованием
Или… Не говорить ничего.
Серьёзно. Ничего.

Это считается неявным (implicit) преобразованием.
То есть компилятор сам додумается преобразовать int в bool, когда это надо. Хочу заметить, что Sourcepawn очень редко таким промышляет, а вот тот же JavaScript этим живёт, откуда и родилась куча мемов про это

Так к чему во-о-о-бще всё, что тут было?
А к тому, что ту функцию можно сократить до

stock bool IsAdmin(int client)
{
	return GetUserFlagBits(client) & ADMFLAG_ROOT;
}

Если нужно проверить, что игрок принадлежит к одному из типов админов (в моем примере это были ADMFLAG_BAN, ADMFLAG_KICK и ADMFLAG_ROOT), то это будет выглядеть так:

stock bool IsAdmin(int client)
{
	return GetUserFlagBits(client) & (ADMFLAG_BAN|ADMFLAG_KICK|ADMFLAG_ROOT);
} 

А если нужно проверить, что игрок в принципе админ (что вообще и должно проверяться, судя по названию функции), то:

stock bool IsAdmin(int client)
{
	return GetUserFlagBits(client);
} 

Да. Это действительно то, к чему всё велось.
Теперь понимаете почему учебники такие толстые?

Топ 10 способов расписать статью из ничего. Рекомендую.

Сообщение отредактировал PawnLomaster: 09 Декабрь 2022 — 13:36

I am trying to take the user input from one method and use it in another. I am confused about the cannot return a value from method whose result type is void error because «userMove» is defined as type int.

public static void move()
{
    System.out.println("What do you want to do?");
    Scanner scan = new Scanner(System.in);
    int userMove = scan.nextInt();
    return userMove;
}

public static void usersMove(String playerName, int gesture)
{
    int userMove = move();

    if (userMove == -1)
    {
        break;
    }

asked Mar 20, 2013 at 8:16

user2181402's user avatar

1

Simply change void to int as you’re returning an int.

public static int move()
{
    System.out.println("What do you want to do?");
    Scanner scan = new Scanner(System.in);
    int userMove = scan.nextInt();
    return userMove;
}

A void method means it returns nothing (ie. no return statement), anything other then void and a return is required.

answered Mar 20, 2013 at 8:17

Daniel Imms's user avatar

Daniel ImmsDaniel Imms

47k19 gold badges147 silver badges164 bronze badges

1

A method which is marked as void means that it does not return anything. It can be seen as a procedure as opposed to a function.

Changing your method signature to public static int move() should fix your problem. Your method would now represent a function, which has a return value.

This Oracle tutorial should provide some useful information.

answered Mar 20, 2013 at 8:18

npinti's user avatar

npintinpinti

51.5k5 gold badges73 silver badges95 bronze badges

/* Pawn compiler — Error message strings (plain and compressed formats) * * Copyright (c) ITB CompuPhase, 2000-2006 * * This software is provided «as-is», without any express or implied warranty. * In no event will the authors be held liable for any damages arising from * the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software in * a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * Version: $Id$ */ // To find unused errors, try this: // for i in {1..182}; do echo -n «Error $i:» ; grep error compiler/*.cpp | grep -E «b$ib» | wc -l; done static const char* errmsg[] = { /*001*/ «expected token: «%s«, but found «%s«n«, /*002*/ «only a single statement (or expression) can follow each «case«n«, /*003*/ «declaration of a local variable must appear in a compound blockn«, /*004*/ «function «%s« is not implementedn«, /*005*/ «function may not have argumentsn«, /*006*/ «must be assigned to an arrayn«, /*007*/ «operator cannot be redefinedn«, /*008*/ «must be a constant expression; assumed zeron«, /*009*/ «invalid array size (negative, zero or out of bounds)n«, /*010*/ «invalid function or declarationn«, /*011*/ «symbol ‘%s‘ already defined — did you use a methodmap before its declaration?n«, /*012*/ «invalid function call, not a valid addressn«, /*013*/ «no entry point (no public functions)n«, /*014*/ «invalid statement; not in switchn«, /*015*/ ««default« case must be the last case in switch statementn«, /*016*/ «multiple defaults in «switch«n«, /*017*/ «undefined symbol «%s«n«, /*018*/ «initialization data exceeds declared sizen«, /*019*/ «cannot use symbol «%s« before it is fully parsedn«, /*020*/ «invalid symbol name «%s«n«, /*021*/ «symbol already defined: «%s«n«, /*022*/ «must be lvalue (non-constant)n«, /*023*/ «array assignment must be simple assignmentn«, /*024*/ ««break« or «continue« is out of contextn«, /*025*/ «function heading differs from prototypen«, /*026*/ «no matching «#if…«n«, /*027*/ «invalid character constantn«, /*028*/ «invalid subscript (not an array or too many subscripts): «%s«n«, /*029*/ «invalid expression, assumed zeron«, /*030*/ «compound statement not closed at the end of file (started at line %d)n«, /*031*/ «unknown directiven«, /*032*/ «array index out of bounds (variable «%s«)n«, /*033*/ «array must be indexed (variable «%s«)n«, /*034*/ «argument does not have a default value (argument %d)n«, /*035*/ «argument type mismatch (argument %d)n«, /*036*/ «empty statementn«, /*037*/ «invalid string (possibly non-terminated string)n«, /*038*/ «extra characters on linen«, /*039*/ «constant symbol has no sizen«, /*040*/ «duplicate «case« label (value %d)n«, /*041*/ «invalid ellipsis, array size is not knownn«, /*042*/ «invalid combination of class specifiersn«, /*043*/ «character constant exceeds range for packed stringn«, /*044*/ «positional parameters must precede all named parametersn«, /*045*/ «too many function argumentsn«, /*046*/ «unknown array size (variable «%s«)n«, /*047*/ «array sizes do not match, or destination array is too smalln«, /*048*/ «arrays do not matchn«, /*049*/ «invalid line continuationn«, /*050*/ «missing function call, cannot use non-static member function as a valuen«, /*051*/ «overloaded operator ‘%s‘ does not return booln«, /*052*/ «array size exceeds memory capacityn«, /*053*/ «number literal contains alphanumeric charactern«, /*054*/ «unmatched closing brace («}«)n«, /*055*/ «start of function body without function headern«, /*056*/ «arrays, local variables and function arguments cannot be public (variable «%s«)n«, /*057*/ «property «%s« has no getter or settern«, /*058*/ «duplicate argument; same argument is passed twicen«, /*059*/ «function argument may not have a default value (variable «%s«)n«, /*060*/ «multiple «#else« directives between «#if … #endif«n«, /*061*/ ««#elseif« directive follows an «#else« directiven«, /*062*/ «number of operands does not fit the operatorn«, /*063*/ «function result tag of operator «%s« must be «%s«n«, /*064*/ «cannot change predefined operatorsn«, /*065*/ «enum struct fields cannot have more than one dimensionn«, /*066*/ «function argument may not be a reference argument or an array (argument «%s«)n«, /*067*/ «variable cannot be both a reference and an array (variable «%s«)n«, /*068*/ «cannot automatically increment values of type ‘%sn«, /*069*/ «arrays in info structs must be unsized and single dimensionn«, /*070*/ «assertion failed%sn«, /*071*/ «user-defined operator must be declared before use (function «%s«)n«, /*072*/ ««sizeof« operator is only valid on variablesn«, /*073*/ «function argument must be an array (argument «%s«)n«, /*074*/ «#define pattern must start with an alphabetic charactern«, /*075*/ «input line too long (after substitutions)n«, /*076*/ «syntax error in the expression, or invalid function calln«, /*077*/ «arrays cannot be indexed by non-integral type ‘%sn«, /*078*/ «function uses both «return« and «return <value>«n«, /*079*/ «inconsistent return types (array & non-array)n«, /*080*/ «‘…’ not allowed in enum struct initializersn«, /*081*/ «enum struct field arrays must have fixed sizesn«, /*082*/ «properties cannot be arraysn«, /*083*/ «methodmap methods cannot return arraysn«, /*084*/ «cannot call constructor for ‘%s‘ as static methodn«, /*085*/ «type «%s« can only be used in new-style declarationsn«, /*086*/ «number literal has invalid digitsn«, /*087*/ «enum struct «%s« cannot refer to itselfn«, /*088*/ «cannot return a value from a void functionn«, /*089*/ «casting a void function is illegaln«, /*090*/ «public functions may not return arrays (symbol «%s«)n«, /*091*/ «more initializers than enum fieldsn«, /*092*/ «number of arguments does not match definitionn«, /*093*/ «cannot divide by zeron«, /*094*/ «cannot apply const qualifier to enum struct field «%s«n«, /*095*/ «type «%s« cannot be applied as a tagn«, /*096*/ «could not find member «%s« in %s «%s«n«, /*097*/ «overflow in integer divisionn«, /*098*/ «type «%s« should be «%s« in new-style declarationsn«, /*099*/ «%s should not have an explicit return typen«, /*100*/ «function prototypes do not matchn«, /*101*/ «fixed dimensions must be after the array name, not on the typen«, /*102*/ «cannot find %s %sn«, /*103*/ «%s was already defined on this %sn«, /*104*/ «cannot find any methods for %sn«, /*105*/ «cannot find method or property «%s.%s«n«, /*106*/ «invalid expression, must be integraln«, /*107*/ «cannot call methods on a functionn«, /*108*/ «resolution operator (::) can only resolve field offsets of enum structsn«, /*109*/ «%s name must start with an uppercase lettern«, /*110*/ «%s has already been defined (previously seen as %s)n«, /*111*/ «cannot index into enum struct «%s«n«, /*112*/ «resolution operator (::) cannot be used on «%s«n«, /*113*/ «constructor for «%s« already existsn«, /*114*/ «missing type, or %s must have the same name as %s «%s«n«, /*115*/ «cannot use delete, %s %s has no destructorn«, /*116*/ «no methodmap or class was found for %sn«, /*117*/ «enum structs cannot be indexed as arraysn«, /*118*/ «custom destructors are no longer supportedn«, /*119*/ «enum struct «%s« must have at least one fieldn«, /*120*/ «methodmap and class signatures must use new-style type declarationsn«, /*121*/ «cannot specify array dimensions on both type and namen«, /*122*/ «expected type expressionn«, /*123*/ «fully-qualified name «%s« is too long, would be truncated to «%s«n«, /*124*/ «unexpected token, expected method or propertyn«, /*125*/ «expected «native«, «get«, or «set«n«, /*126*/ «%s for %s already existsn«, /*127*/ «property getters cannot accept extra argumentsn«, /*128*/ «cannot return an array of indeterminate lengthn«, /*129*/ «cannot mix methodmaps and classes with inheritancen«, /*130*/ «cannot coerce functions to valuesn«, /*131*/ «cannot coerce object type %s to non-object type %sn«, /*132*/ «cannot coerce non-object type %s to object type %sn«, /*133*/ «cannot coerce unrelated object types %s and %sn«, /*134*/ «type mismatch (expected «%s«, got «%s«)n«, /*135*/ «cannot use enum struct type «%s« in nativesn«, /*136*/ «reference is redundant, enum struct types are array-liken«, /*137*/ «cannot mix reference and array typesn«, /*138*/ «const was specified twicen«, /*139*/ «could not find type «%s«n«, /*140*/ «function ‘%s‘ does not return a valuen«, /*141*/ «natives, forwards, and public functions cannot return arraysn«, /*142*/ «unexpected array expressionn«, /*143*/ «new-style declarations should not have «new«n«, /*144*/ «void cannot be used as a variable typen«, /*145*/ «invalid type expressionn«, /*146*/ «#pragma newdecls must be required or optionaln«, /*147*/ «new-style declarations are requiredn«, /*148*/ «cannot assign null to a non-nullable typen«, /*149*/ «no getter found for property %sn«, /*150*/ «setter must take exactly one extra argument with type %sn«, /*151*/ «unmatched opening brace (‘{‘) (line %d)n«, /*152*/ «no setter found for property %sn«, /*153*/ «Array-based enum structs have been removed. See https://wiki.alliedmods.net/SourcePawn_Transitional_Syntax#Enum_Structsn«, /*154*/ «cannot assign INVALID_FUNCTION to a non-function typen«, /*155*/ «expected newline, but found ‘%sn«, /*156*/ «invalid ‘using’ declarationn«, /*157*/ «%s‘ is a reserved keywordn«, /*158*/ «multi-tags are no longer supportedn«, /*159*/ «brackets after variable name indicate a fixed-size array, but size could not be determined — « «either specify sizes, an array initializer, or use dynamic syntax (such as ‘char[] x’)n«, /*160*/ «brackets in between type and variable name indicate a dynamic-size array, but a fixed-size « «initializer was givenn«, /*161*/ «brackets after variable name indicate a fixed-size array, but a dynamic size was given — did « «you mean to use ‘new %s[size]’ syntax?n«, /*162*/ «cannot create dynamic arrays in global scope — did you mean to « «create a fixed-length array?n«, /*163*/ «indeterminate array size in «sizeof« expression (symbol «%s«)n«, /*164*/ «allocated array type ‘%s‘ doesn’t match original type ‘%sn«, /*165*/ «cannot create dynamic arrays in static scope — did you mean to create a fixed-length array « «with brackets after the variable name?n«, /*166*/ «cannot use ‘this’ outside of a methodmap method or propertyn«, /*167*/ «cannot use delete, %s do not have destructorsn«, /*168*/ «re-tagging enums is no longer supportedn«, /*169*/ «cannot tag an enum as implicit-intn«, /*170*/ «creating new object ‘%s‘ requires using ‘new’ before its constructorn«, /*171*/ «cannot use ‘new’ with non-object-like methodmap ‘%sn«, /*172*/ «methodmap ‘%s‘ does not have a constructorn«, /*173*/ «%s‘ is a newly reserved keyword that may be used in the future; use a different name as an « «identifiern«, /*174*/ «symbol ‘%s‘ is a type and cannot be used as a valuen«, /*175*/ «constructors cannot be staticn«, /*176*/ «non-static method or property ‘%s‘ must be called with a value of type ‘%sn«, /*177*/ «static method ‘%s‘ must be invoked via its type (try ‘%s.%s‘)n«, /*178*/ «cannot coerce %s[] to %s[]; storage classes differn«, /*179*/ «cannot assign %s[] to %s[], storage classes differn«, /*180*/ «function return type differs from prototype. expected ‘%s‘, but got ‘%sn«, /*181*/ «function argument named ‘%s‘ differs from prototypen«, /*182*/ «functions that return arrays cannot be used as callbacksn«, /*183*/ «brackets after variable name indicates a fixed-size array, but « «size is missing or not constantn«, /*184*/ «implicit dynamic array has a dimension of unspecified sizen«, /*185*/ «invalid default array initializern«, }; static const char* warnmsg[] = { /*200*/ «symbol «%s« is truncated to %d charactersn«, /*201*/ «redefinition of constant/macro (symbol «%s«)n«, /*202*/ «number of arguments does not match definitionn«, /*203*/ «symbol is never used: «%s«n«, /*204*/ «symbol is assigned a value that is never used: «%s«n«, /*205*/ «redundant code: constant expression is zeron«, /*206*/ «redundant test: constant expression is non-zeron«, /*207*/ «unknown #pragman«, /*208*/ «function with tag result used before definition, forcing reparsen«, /*209*/ «function has explicit ‘int’ tag but does not return a valuen«, /*210*/ «possible use of symbol before initialization: «%s«n«, /*211*/ «possibly unintended assignmentn«, /*212*/ «possibly unintended bitwise operationn«, /*213*/ «tag mismatch (expected «%s«, got «%s«)n«, /*214*/ «possibly a «const« array argument was intended: «%s«n«, /*215*/ «expression has no effectn«, /*216*/ «nested commentn«, /*217*/ «inconsistent indentation (did you mix tabs and spaces?)n«, /*218*/ «old style prototypes used with optional semicolumnsn«, /*219*/ «local variable «%s« shadows a variable at a preceding leveln«, /*220*/ «expression with tag override must appear between parenthesesn«, /*221*/ «label name «%s« shadows tag namen«, /*222*/ «number of digits exceeds rational number precisionn«, /*223*/ «redundant «sizeof«: argument size is always 1 (symbol «%s«)n«, /*224*/ «user warning: %sn«, /*225*/ «unreachable coden«, /*226*/ «a variable is assigned to itself (symbol «%s«)n«, /*227*/ «illegal charactern«, /*228*/ «enum multiplers are deprecated and will be removed in the next releasen«, /*229*/ «index tag mismatch (symbol «%s«)n«, /*230*/ «symbol «%s« is not a preprocessor symbol; this behavior is undefined and will be removed in the futuren«, /*231*/ «unused231n«, /*232*/ «output file is written, but with compact encoding disabledn«, /*233*/ «unused233n«, /*234*/ «symbol «%s« is marked as deprecated: %sn«, /*235*/ «unused235n«, /*236*/ «unused236n«, /*237*/ «coercing functions to and from primitives is unsupported and will be removed in the futuren«, /*238*/ «%s:’ is an illegal cast; use view_as<%s>(expression)n«, /*239*/ «%s‘ is an illegal tag; use %s as a typen«, /*240*/ «%s:’ is an old-style tag operation; use view_as<type>(expression) insteadn«, /*241*/ «scalar assignment to array is deprecated; use «{ <val>, … }« insteadn«, /*242*/ «function «%s« should return an explicit valuen«, /*243*/ «syntax is deprecated; use parenthesis insteadn«, /*244*/ «field ‘%s‘ was specified twicen«, /*245*/ «function %s implements a forward but is not marked as publicn«, /*246*/ «function %s returns an array but return type is not marked as an arrayn«, /*247*/ «include paths should be enclosed in «quotes« or <angle brackets>n«, /*248*/ «character is not utf-8 encodedn«, /*249*/ «function name is always true — possible missing parenthesis?n«, /*250*/ «pragma has no effectn«, /*251*/ «const variable was not initializedn«, }; static const char* errmsg_ex[] = { /*400*/ «function «%s« must return a valuen«, /*401*/ «cannot specify ‘…’ arguments more than oncen«, /*402*/ «cannot specify additional arguments after ‘…’n«, /*403*/ «not yet implementedn«, /*404*/ «enum multiplers are no longer supportedn«, /*405*/ «invalid assignmentn«, /*406*/ «operator %s(%s) was used before declarationn«, /*407*/ «operator %s(%s, %s) was used before declarationn«, /*408*/ «recursion detected in user operatorn«, /*409*/ «methodmap %s referenced before definitionn«, /*410*/ «methodmap inheritance forms a cyclen«, /*411*/ «cannot determine fixed array size of return valuen«, /*412*/ «function %s implements a forward but is not marked as publicn«, /*413*/ «returned array does not have the same dimension count as return typen«, /*414*/ «include statements are only allowed at the top-level scopen«, /*415*/ «assertion failedn«, /*416*/ «user error: %sn«, /*417*/ «cannot read from file: «%s«n«, /*418*/ «deprecated syntax; see https://wiki.alliedmods.net/SourcePawn_Transitional_Syntax#Typedefsn«, /*419*/ «cannot write to file: «%s«n«, /*420*/ «unhandled AST type: %dn«, /*421*/ «too many functionsn«, /*422*/ «no more source locations, too much source textn«, /*423*/ «internal compiler error: error propagated with no messagen«, /*424*/ «integer literal contains no digitsn«, /*425*/ «exponential must be followed by integern«, /*426*/ «macro arguments must be %% followed by a single digitn«, /*427*/ «macro argument %%%d already usedn«, /*428*/ «invalid macro argument, mismatched parenthesisn«, /*429*/ «wrong number of macro arguments (expected %s, got %s)n«, /*430*/ «invalid macro definitionn«, /*431*/ «script uses too much memory, cannot compilen«, /*432*/ «type %s was already declared as %sn«, };

A «compile-time» error is one which prevents your code from compiling. This page describes 14 of the most common errors you will encounter. Compile-time errors are divided into three categories:

  1. Lexical: These generally occur when you include disallowed characters in your code (e.g. int #people = 10;).
  2. Syntactical: These occur when your code is «out of order» (e.g. for (int i=0; i++; i<10)).
  3. Semantic: These occur when the meaning of your code is unclear (e.g. two variables with the same name).

Note that the exact wording of these errors may vary, depending on which development environment you are using.

Errors described on this page (click to jump to that error):

  1. Cannot return a value from a method of type void
  2. ‘Class’ or ‘interface’ expected
  3. Class should be delcared abstract; it does not define…
  4. Else without if
  5. Expected: ;, {, }, (, or )
  6. Identifier expected / Illegal character
  7. Incompatible types / Inconvertible types (cannot cast)
  8. Method does not return a value / Missing return statement
  9. Method not found
  10. Not a statement
  11. Return type required
  12. Unreachable statement
  13. Variable already defined
  14. Variable not declared

Cannot return a value from a method of type void

When a method is declared as having a return type of void, it cannot contain any return statements which return a value (it can, however, contain a return statement by itself, which will simply end the execution of the method). This problem is usually caused by accidentally making a method be of type void when it shouldn’t be or by accidentally including a return statement where there shouldn’t be one.

Example 1: Incorrect Code Example 1: Fixed Code

This method has a return type of void and so it may not return any values.

We change the return type of this method in order to fix the problem.

01  public void getName()
02  {   return this.name;
03  }
01  public String getName()
02  {   return this.name;
03  }


‘Class’ or ‘interface’ expected

This error will most likely be caused when you omit the keyword class or interface, as seen in the example below.

Example 1: Incorrect Code Example 1: Fixed Code

Here, we do not have either keyword present.

We add in class or interface, depending on our intentions within the program.

01  public Test
02  {
03      public void someMethod()
04      {   System.out.println("Hello, world!");
05      }
06  }
01  public class Test
02  {
03      public void someMethod()
04      {   System.out.println("Hello, world!");
05      }
06  }

— OR —

01  public interface Test
02  {
03      public void someMethod();
04  }

Class should be delcared abstract; it does not define…

This error arises when implementing an interface. Recall that when you say implements SomeInterface for a certain class, you guarantee that you have written all of the methods specified within that interface. If you are missing at least one of the methods which is listed in the interface, Java will not let your code compile.

As an example, consider an interface TestInterface which looks like:

public interface TestInterface
{
  public int methodOne();
  public String methodTwo(String z);
  public boolean methodThree();
}

Using TestInterface, consider the following example.

Example 1: Incorrect Code Example 1: Fixed Code

We receive an error message in this case because we implement TestInterface but do not include methodThree().

To allow this program to compile, we add in a «stub» for the required method. This is the quick way around the problem: in most cases, you will want to actually write a method body for this method so that it does what it was intended to do.

01  public class Test implements TestInterface
02  {
03      private int y = 700;
04  
05      public int methodOne()
06      {   int x = this.y - 1;
07          return x;
08      }
09  
10      public String methodTwo(String z)
11      {   String label = "Val: " + z;
12          return label;
13      }
14  }
01  public class Test implements TestInterface
02  {
03      private int y = 700;
04  
05      public int methodOne()
06      {   int x = this.y - 1;
07          return x;
08      }
09  
10      public String methodTwo(String z)
11      {   String label = "Val: " + z;
12          return label;
13      }
14
15      public boolean methodThree()
16      {   return false;
17      }
18  }

Note that when you are implementing methods in the interface, the method signatures must match exactly. That is, if the interface expects that you implement a method public String longer(String a, String b), then you must write a method with exactly the same name, exactly the same return type, and exactly the same parameters (in this case, two Strings).


Else without if

This error occurs when you have an else or else if clause without an if clause above it. This is most likely because you have accidentally forgotten/added extra { or } braces, or you have placed an else clause in the wrong place, as illustrated in the example below. The key idea is that every else clause needs to have an associated if clause which occurs before it.

Example 1: Incorrect Code Example 1: Fixed Code

Here, we have accidentally placed the else clause within the if clause.

We place the else clause after the if clause, which correctly associates them.

01  String text = "abaaba";
02    
03  if (text.length() >= 6)
04  {   text += text;    
05  else
06  {   text += text.substring(3);
07  }
08  }
01  String text = "abaaba";
02    
03  if (text.length() >= 6)
04  {   text += text;
05      
06  }
07  else
08  {   text += text.substring(3);
09  }

Expected: ;, {, }, (, or )

Java is very specific about use of characters such as semicolons, brackets, or braces. Forgetting a semicolon is the simplest of these errors, and is fixed by placing a semicolon at the end of the line which causes the error. Brackets can be more complicated, because you may have to read through several nested if statements or loops in order to make sure that all brackets «match up» with each other properly. This is one of the reasons why indenting your code properly is a good idea.

Example 1: Incorrect Code Example 1: Fixed Code

Here, lines 6, 7, and 10 will give us compile-time errors because we have forgot to include brackets, a semicolon, and a close-brace respectively.

We add these in to fix the problems.

01  public class Test
02  { 
03      public void getName()
04      {   int k = 10;  
05    
06          if k == 10
07          { k++
08          }
09      }
10
01  public class Test
02  { 
03      public void getName()
04      {   int k = 10;  
05    
06          if (k == 10)
07          { k++;
08          }
09      }
10  }

Identifier expected / Illegal character

An identifier is another term for a variable. In Java, every variable name must begin with a letter/underscore and can then have any combination of letters, numbers, and underscores. The example below illustrates two cases you may run into.

Example 1: Incorrect Code Example 1: Fixed Code

The variable name 10Names is not allowed because it begins with a number. The variable name wtPer#ofPeople is not allowed bacause it contains a pound sign.

To fix this, we change these to valid variable names.

01  private String[] 10Names;
02  private int wtPer#ofPeople;
01  private String[] tenNames;
02  private int wtPerNumberOfPeople;


Incompatible types / Inconvertible types (cannot cast)

In a Java assignment statement, the type of the variable on the left hand side must be the same as the type of the variable on the right hand side (or it needs to be able to be cast first in order to make it work). The example below would give three ‘incompatible types’ error messages.

Example 1: Incorrect Code Example 1: Fixed Code

Lines 5, 6, and 7 all give us errors. This is because an int cannot be assigned to a String, a boolean cannot be assigned to an int, and a String cannot be assigned to a boolean, respectively.

We change these three statements so that the primitive type / Object type is the same on both sides of the assignment (=) sign.

01  String theAge = "Twenty-two";
02  int x = 22;
03  boolean b = false;
04    
05  theAge = x;
06  x = b;
07  b = theAge;
01  String theAge = "Twenty-two";
02  int x = 22;
03  boolean b = false;
04    
05  theAge = "Thirty-three";
06  x = 33;
07  b = true;

Note that one common exception to this rule is that an int value can be assigned to a char value and vice-versa (this is because every character is actually represented as an integer ASCII value).

This error may also occur when trying to pass a value of one type into a method which expects another. An example of this is below.

Example 2: Incorrect Code Example 2: Fixed Code

Here, we try to pass a String as an actual parameter into a method which has an int as its formal parameter (these two types are incompatible).

To fix this, we change the type of the variable which is being passed. Alternately, we could have also changed the type of the actual parameter to be a String and then re-coded the method calcNewAge accordingly.

01  String theAge = "Twenty-two";
02  int result = calcNewAge(theAge);
03  
04  public int calcNewAge(int theAge)
05  {   return theAge / 2 + 7;
06  }
01  int theAge = 22;
02  int result = calcNewAge(theAge);
03  
04  public int calcNewAge(int theAge)
05  {   return theAge / 2 + 7;
06  }

You may also get a similar error if you are attempting to cast incorrectly. Recall that a primitive type may not be cast to an object or vice-versa. When casting between two objects, recall that object «A» may be cast to be of the same type as object «B» only if B’s class extends A’s class. As an example, consider a class Cat which extends the class Animal.

Example 3: Incorrect Code Example 3: Fixed Code

Here, lines 2 and 3 are incorrect attempts at casting because neither Animal nor String are subclasses of Cat.

Line 2 is a correct cast because Cat is a subclass of Animal (a Cat is an Animal, but an Animal is not necessarily a Cat).

01  Cat c = new Cat("Sparky", "black");
02  Animal a = (Animal) c;
03  String theCat = (String) c;
01  Animal a = new Animal("Sparky");
02  Cat c = (Cat) a;

Method does not return a value / Missing return statement

In Java, every method which does not have a return type of void must have at least one return statement.

Example 1: Incorrect Code Example 1: Fixed Code

The return type of this method is String, so Java expects that we have a return statement which returns a value with this type. As written, this method does not return anything.

Instead of printing these values to the screen, we return them.

01  public String getFortune()
02  {   if (this.age >= 19)
03      {   System.out.println("Good times ahead");
04      } 
05      else
06      {   System.out.println("Hailstorms unavoidable");
07      }
08  }
01  public String getFortune()
02  {   if (this.age >= 19)
03      {   return "Good times ahead";
04      } 
05      else
06      {   return "Hailstorms unavoidable";
07      }
08  }

This compile-time error can have a very subtle point which is often overlooked. If the return type of a method is not void, Java needs to ensure that the method will return a value in every possible case. That is, if all of your return statements are nested within if statements, Java will disallow the compilation process to continue because there is a chance that no return statement will be reached. The example below illustrates this.

Example 2: Incorrect Code Example 2: Fixed Code

In this example, we get a compile-time error because Java sees a possibility of this method not returning a value (if this.age is 99, for example).

To fix this, we ensure that the method will return a value in all possible cases by adding an else clause.

01  public String chatMethod()
02  {   if (this.age <= 18)
03      {   return "MSN";
04      } 
05      else if (this.age > 19 && this.age <= 30)
06      {   return "ICQ";
07      }
08  }

01  public String chatMethod()
02  {   if (this.age <= 18)
03      {   return "MSN";
04      } 
05      else if (this.age > 19 && this.age <= 30)
06      {   return "ICQ";
07      }
08      else
09      {   return "BBS";
10      }
11  }

Note that an easy way to «fix» this error is to simply add a meaningless return statement at the end of the method, such as return -1; or return null;. This often leads to problems elsewhere, such as causing the method to return unintended values.


Method not found

In Java, recall that a method’s signature consists of the method’s name and the types of its actual parameters. For example, the method public void move(int howFar) has the signature move(int). When a method call is made, a method with a signature exactly matching that of the method call must exist (e.g. the method name, the number of parameters, and the types of all parameters must match exactly). This error is illustrated below.

Example 1: Incorrect Code Example 1: Fixed Code

Line 3 calls a method which has signature larger(String, String). However, the method at line 5 has signature larger(int, int). These two signatures do not match (e.g. there exists no method with signature larger(String, String)), so an error is produced.

To fix this, we can modify the larger so that it has a matching signature to our method call. Alternately, we could have left the current method alone and written another (overloaded) method with the appropriate signature.

01  String first = "CN Tower";
02  String second = "Calgary Tower";
03  String res = this.larger(first, second);
04  
05  public int larger(int a, int b)
06  {   if (a > b)
07      {   return a;
08      } else
09      {   return b;
10      }
11  }
01  String first = "CN Tower";
02  String second = "Calgary Tower";
03  String res = this.larger(first, second);
04  
05  public String larger(String a, String b)
06  {   if (a.length() > b.length())
07      {   return a;
08      } else
09      {   return b;
10      }
11  }

Also note that this error may occur if you do not have the correct import statements at the top of your class.


Not a statement

Each line of Java code must have some sort of meaningful purpose. The compile-time error «not a statement» is usually the result of typing only part of a statement, leaving it incomplete and meaningless. One example of how this may occur (there are many) is seen below. In general, asking yourself «what was I trying to do with this line of code?» is sufficient to fix the problem.

Example 1: Incorrect Code Example 1: Fixed Code

Line 5 will cause the error in this case, as the line grades[1]; is completely meaningless by itself, as it does not give any instruction to the compiler.

We change this line to be a valid, meaningful statement («set the value of x to be the value of the array grades at element 1″). This is just one possible way of fixing the problem (it depends on how you intend things to work).

01  int grades[] = new int[2];
02  int x;
03  grades[0] = 96;
04  grades[1] = 93;
05  grades[1];
06  System.out.println(x);

01  int grades[] = new int[2];
02  int x;
03  grades[0] = 96;
04  grades[1] = 93;
05  x = grades[1];
06  System.out.println(x);

Return type required

For each method, Java requires a return type (e.g. String, int, boolean). Note that void is also considered to be a «return type» even though a method with a void return type does not return a value.

Example 1: Incorrect Code Example 1: Fixed Code

An error is caused because the theAnswer() method does not have a declared return type.

Two possible solutions to this problem are suggested (each would depend on the context of how the method is to be actually used in your program).

01  private theAnswer()
02  {   System.out.println("42");
03  }
01  private void theAnswer()
02  {   System.out.println("42");
03  }

— OR —

01  private int theAnswer()
02  {   return 42;
03  }

Unreachable statement

This error usually occurs if you have a statement placed directly after a return statement. Since Java executes code line-by-line (unless a method call is made), and since a return statement causes the execution of the program to break out of that method and return to the caller, then anything placed directly after a return statement will never be reached.

Example 1: Incorrect Code Example 1: Fixed Code

Line 4 is directly after a return statement, so it cannot be reached because the method will end at line 3.

We switch lines 3 and 4 to ensure that nothing is after the return statement.

01  public String oneMoreA(String orig)
02  {   String newStr = orig + "A";
03      return newStr;
04      this.counter++;
05  }
01  public String oneMoreA(String orig)
02  {   String newStr = orig + "A";
03      this.counter++;

04      return newStr;
05  }

You (may) also get this error if you place a statement outside of a method, which could be the result of { and } braces not being matched up properly.


Variable already defined

This compile-time error is typically caused by a programmer attempting to declare a variable twice. Recall that a statment such as int temp; declares the variable named temp to be of type int. Once this declaration has been made, Java can refer to this variable by its name (e.g. temp = 15;) but does not let the programmer declare it a second time by including the variable type before the name, as seen in the example below.

Example 1: Incorrect Code Example 1: Fixed Code

Here, we have declared the variable temperature twice: once at line 3 and then again at line 6.

We have fixed the problem by only declaring the variable once (at line 3) and we refer only to the variable’s name on line 6.

01  int a = 7;
02  int b = 12;
03  int temperature = Math.max(a, b);
04    
05  if (temperature > 10)
06  {   int temperature = 0;
07  }
01  int a = 7;
02  int b = 12;
03  int temperature = Math.max(a, b);
04    
05  if (temperature > 10)
06  {   temperature = 0;
07  }

You may also get this error if you have tried to declare two variables of different types using the same variable name (in Java, every variable must have a unique name). The example below illustrates this using two variables of type int and String.

Example 2: Incorrect Code Example 2: Fixed Code

Here we are trying to declare two variables using the same variable name of temperature. This is not allowed, regardless of the types of the variables.

We fix the problem by ensuring that each variable has a unique name.

01  int temperature = 22;
02  String temperature = "Hot Outside";
01  int temperature = 22;
02  String tempDescription = "Hot Outside";

The only time where repetition of variable names or declarations are allowed is if the two variables are in different scopes. Recall that the scope of a variable is determined by the set of braces, { and }, in which it is enclosed. This is illustrated in the two examples below.

Example 3: Correct Code Example 4: Correct Code

This is allowed because the delarations on lines 4 and 7 are being done within different scopes. One is within the scope of the if statement, and the other is within the scope of the else if statement.

Similarly, this is also allowed because temp is declared in two different methods and will therefore be done within different scopes.

01  int temp = 22;
02
03  if (temp >= 20)
04  {   String desc = "Hot";
05  }
06  else if (temp >= 10 && temp < 20 )
07  {   String desc = "Nice";
08  }

01  public void cold()
02  {   int temp = -27;
03  }
04
05  public void hot()
06  {   int temp = 27;
07  }

Variable not declared

This error occurs when a variable is not declared within the same (or an «outer») scope in which it is used. Recall that the scope of a variable declaration is determined by its location with { and } braces. The example below illustrates a simple case of this error. To fix this problem, make sure that the variable is declared either in the same scope in which it is being used, or it being delcared in an «outer» scope.

Example 1: Incorrect Code Example 1: Fixed Code

The variable balance is declared within the scope of the first if statement, so line 9 will cause an error.

To fix the problem, we declare balance in the scope of the entire method so that it can be referred to in all places within the method.

01  boolean newAcct = true;
02  double deposit = 17.29;
03    
04  if (newAcct == true)
05  {   double balance = 100.0;
06  }
07    
08  if (deposit > 0)
09  {   balance += deposit;
10  }
01  boolean newAcct = true;
02  double deposit = 17.29;
03  double balance = 0;

04    
05  if (newAcct == true)
06  {   balance = 100.0;
07  }
08    
09  if (deposit > 0)
10  {   balance += deposit;
11  }

Return to Main Page

Created by Terry Anderson (tanderso at uwaterloo dot ca) for use by ISG, Spring 2005

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Error 08001 timeout expired
  • Error 08 шерхан mobicar
  • Error 079 inconsistent return types array non array
  • Error 078 function uses both return and return value
  • Error 075 input line too long after substitutions павно

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии