Compiler and linker errors

C++ "expected primary-expression before": causes and fixes

The compiler reports “expected primary-expression” when it reaches a place that requires a value expression but finds a type, declaration, or unmatched delimiter. Common variants say “before 'int'” or “before ')' token.” GCC reports the type-in-call case before 'int' and the misplaced-delimiter case before ')' token.

Read the diagnostic

A primary expression is a basic expression that names a value, such as a variable, literal, or function call. The message points near the token where the parser can no longer continue; the actual mistake may be just before that token. Read the first diagnostic and inspect the preceding punctuation before changing later lines. GCC may print a caret and a note about the token. MSVC reports syntax errors with different codes and wording; it does not promise a one-to-one translation for every parser state.

Failing C++17 example

#include <iostream>

int area(int width) { return width * width; }

int main() {
    std::cout << area(int width) << '\n';
    return 0;
}

GCC diagnostic core:

error: expected primary-expression before 'int'

MSVC reports C2144: syntax error: 'int' should be preceded by ';'.

Fixed example

#include <iostream>

int area(int width) { return width * width; }

int main() {
    int width = 4;
    std::cout << area(width) << '\n';
    return 0;
}

Expected output:

16

Pass values, not parameter declarations

Function declarations include types and parameter names, but function calls supply expressions only. Writing calculate(int width) in a call repeats declaration syntax where the compiler expects a value. Call calculate(width) after declaring width. If the function expects an integer, the compiler knows that from its declaration. Do not add a cast just to hide a misplaced type name.

Balance calls and expressions

A missing closing parenthesis can make the next token appear where an expression should be. Compare each opening parenthesis, bracket, and brace with its matching close. Check commas between arguments and avoid a trailing operator with no right-hand operand. Use the caret as a location clue, then inspect the complete statement. A single missing bracket can produce several follow-on errors, so fix the earliest syntax problem and compile again. An empty argument such as total(1, ) also leaves the parameter without an expression; remove the extra comma or provide the missing value.

Use an object before the dot

A type names a category of values; it is not an object with member values. In std::string.size(), std::string is the type, so the dot has no object on its left. Create a string object, then call size() on that object.

Failing C++17 example

#include <iostream>
#include <string>

int main() {
    std::cout << std::string.size() << '\n';
    return 0;
}

GCC diagnostic core:

error: expected primary-expression before '.' token

MSVC reports C2275 (“expected an expression instead of a type”). Diagnostic wording can vary by compiler version.

Fixed example

#include <iostream>
#include <string>

int main() {
    std::string text = "cat";
    std::cout << text.size() << '\n';
    return 0;
}

Expected output:

3

Avoid fixes that hide the cause

Do not insert a random semicolon at the caret. A semicolon can end a statement but cannot supply a missing expression. Do not treat every “expected primary-expression” diagnostic as a missing variable; the offending token and surrounding grammar matter. If a macro appears in the line, inspect its expansion because preprocessing can change the tokens the compiler sees. Keep the smallest correction that restores the intended expression and scope.

Exercise

Remove the misplaced closing parenthesis after the multiplication operator. The corrected expression prints 11.

Broken program

#include <iostream>

int main() {
    std::cout << (5 + 2 * ) << '\n';
    return 0;
}

Compiler diagnostic core:

error: expected primary-expression before ')' token

Sample input: none.

Expected output after the fix:

11

Hint 1: Read from the multiplication operator onward. Hint 2: Remove the extra closing parenthesis.

Show one possible solution
#include <iostream>

int main() {
    std::cout << (5 + 2 * 3) << '\n';
    return 0;
}

Expected output:

25

Keep learning with CppPath

Continue with the Compiler Errors & Warnings lesson. The full lesson includes a quiz and a checked coding challenge with a free account.