I recently got a C++ program for my school test.
#include<iostream.h>
#define convert(p,q) p+2*q
void main()
{
int a,b,result;
cin>>a>>b;
result=convert(a,b);
cout<<result;
}
This works correctly.
When I put p+2*q in {}, it gives me the error :
"Expression syntax in function main()"
Now when I declare result just before output, like this:
int result=convert(a,b);
It works. Why and why not?
Avoid using macros if you have trouble understanding what the compiler complains about. This is what your code looks like when the macro is expanded, when you put the extra {}
result={a+2*b}
And this is what it looks like with the declaration on the same line
int result={a+2*b}
Before the C++11 standard, the former is a syntax error. Since C++11, it is copy-list-initialization of a temporary (see the syntax labeled (10) ).
The latter is aggregate initialization.
Related
struct T{ double x};
In C, it creates no problem.
But in C++, it gives the following compilation error:
expected ';' at end of member declaration.
From C11, "Structure and union specifiers, syntax" (6.7.2.1/1):
struct-declaration:
specifier-qualifier-list struct-declarator-listopt ;
Each element of a struct ends in a semicolon. Your claim that there is "no problem" is not based on what the C specification says. If your compiler accepts such code, it is not a conforming C compiler, or you are not using it correctly. (Some compilers have a configurable level of standards conformance.)
The GCC parser for C grammar is implemented as follows:
/* If no semicolon follows, either we have a parse error or
are at the end of the struct or union and should
pedwarn. */
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
c_parser_consume_token (parser);
else
{
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
pedwarn (c_parser_peek_token (parser)->location, 0,
"no semicolon at end of struct or union");
else if (parser->error
|| !c_parser_next_token_starts_declspecs (parser))
{
c_parser_error (parser, "expected %<;%>");
c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
break;
}
/* If we come here, we have already emitted an error
for an expected `;', identifier or `(', and we also
recovered already. Go on with the next field. */
}
It calls function pedwarn on a missing semicolon.
The definition of pedwarn can be found here. It reads:
pedwarn is for code that is accepted by GCC but it should be rejected or diagnosed according to the current standard, or it conflicts with the standard (either the default or the one selected by -std=). It can also diagnose compile-time undefined behavior (but not runtime UB). pedwarns become errors with -pedantic-errors.
Why output of struct T{ double x}; different in C and C++?
The example struct definition is ill-formed in both C and C++.
C and C++ are different languages, they use different parsers (or whatever component of the compiler detects this error). The output is different because different decisions were made by people when they implemented the parser of the C compiler, than were made when the C++ parser was implemented.
Latter decided to issue an error, the former issues merely a warning, and successfully compiles despite the bug. Another C compiler can refuse to compile as well, and a C++ compiler can accept the program (as long as it produces a warning).
Generally, C language likes semicolon much more than Pascal (Delphi). In your case, C accepts struct T{ double x};, but C++ already requires struct T{ double x;};
What are undeclared identifier errors? What are common causes and how do I fix them?
Example error texts:
For the Visual Studio compiler: error C2065: 'cout' : undeclared identifier
For the GCC compiler: 'cout' undeclared (first use in this function)
They most often come from forgetting to include the header file that contains the function declaration, for example, this program will give an 'undeclared identifier' error:
Missing header
int main() {
std::cout << "Hello world!" << std::endl;
return 0;
}
To fix it, we must include the header:
#include <iostream>
int main() {
std::cout << "Hello world!" << std::endl;
return 0;
}
If you wrote the header and included it correctly, the header may contain the wrong include guard.
To read more, see http://msdn.microsoft.com/en-us/library/aa229215(v=vs.60).aspx.
Misspelled variable
Another common source of beginner's error occur when you misspelled a variable:
int main() {
int aComplicatedName;
AComplicatedName = 1; /* mind the uppercase A */
return 0;
}
Incorrect scope
For example, this code would give an error, because you need to use std::string:
#include <string>
int main() {
std::string s1 = "Hello"; // Correct.
string s2 = "world"; // WRONG - would give error.
}
Use before declaration
void f() { g(); }
void g() { }
g has not been declared before its first use. To fix it, either move the definition of g before f:
void g() { }
void f() { g(); }
Or add a declaration of g before f:
void g(); // declaration
void f() { g(); }
void g() { } // definition
stdafx.h not on top (VS-specific)
This is Visual Studio-specific. In VS, you need to add #include "stdafx.h" before any code. Code before it is ignored by the compiler, so if you have this:
#include <iostream>
#include "stdafx.h"
The #include <iostream> would be ignored. You need to move it below:
#include "stdafx.h"
#include <iostream>
Feel free to edit this answer.
Consider a similar situation in conversation. Imagine your friend says to you, "Bob is coming over for dinner," and you have no idea who Bob is. You're going to be confused, right? Your friend should have said, "I have a work colleague called Bob. Bob is coming over for dinner." Now Bob has been declared and you know who your friend is talking about.
The compiler emits an 'undeclared identifier' error when you have attempted to use some identifier (what would be the name of a function, variable, class, etc.) and the compiler has not seen a declaration for it. That is, the compiler has no idea what you are referring to because it hasn't seen it before.
If you get such an error in C or C++, it means that you haven't told the compiler about the thing you are trying to use. Declarations are often found in header files, so it likely means that you haven't included the appropriate header. Of course, it may be that you just haven't remembered to declare the entity at all.
Some compilers give more specific errors depending on the context. For example, attempting to compile X x; where the type X has not been declared with clang will tell you "unknown type name X". This is much more useful because you know it's trying to interpret X as a type. However, if you have int x = y;, where y is not yet declared, it will tell you "use of undeclared identifier y" because there is some ambiguity about what exactly y might represent.
In C and C++ all names have to be declared before they are used. If you try to use the name of a variable or a function that hasn't been declared you will get an "undeclared identifier" error.
However, functions are a special case in C (and in C only) in that you don't have to declare them first. The C compiler will the assume the function exists with the number and type of arguments as in the call. If the actual function definition does not match that you will get another error. This special case for functions does not exist in C++.
You fix these kind of errors by making sure that functions and variables are declared before they are used. In the case of printf you need to include the header file <stdio.h> (or <cstdio> in C++).
For standard functions, I recommend you check e.g. this reference site, and search for the functions you want to use. The documentation for each function tells you what header file you need.
I had the same problem with a custom class, which was defined in a namespace. I tried to use the class without the namespace, causing the compiler error "identifier "MyClass" is undefined".
Adding
using namespace <MyNamespace>
or using the class like
MyNamespace::MyClass myClass;
solved the problem.
These error meassages
1.For the Visual Studio compiler: error C2065: 'printf' : undeclared identifier
2.For the GCC compiler: `printf' undeclared (first use in this function)
mean that you use name printf but the compiler does not see where the name was declared and accordingly does not know what it means.
Any name used in a program shall be declared before its using. The compiler has to know what the name denotes.
In this particular case the compiler does not see the declaration of name printf . As we know (but not the compiler) it is the name of standard C function declared in header <stdio.h> in C or in header <cstdio> in C++ and placed in standard (std::) and global (::) (not necessarily) name spaces.
So before using this function we have to provide its name declaration to the compiler by including corresponding headers.
For example
C:
#include <stdio.h>
int main( void )
{
printf( "Hello World\n" );
}
C++:
#include <cstdio>
int main()
{
std::printf( "Hello World\n" );
// or printf( "Hello World\n" );
// or ::printf( "Hello World\n" );
}
Sometimes the reason of such an error is a simple typo. For example let's assume that you defined function PrintHello
void PrintHello()
{
std::printf( "Hello World\n" );
}
but in main you made a typo and instead of PrintHello you typed printHello with lower case letter 'p'.
#include <cstdio>
void PrintHello()
{
std::printf( "Hello World\n" );
}
int main()
{
printHello();
}
In this case the compiler will issue such an error because it does not see the declaration of name printHello. PrintHello and printHello are two different names one of which was declared and other was not declared but used in the body of main
It happened to me when the auto formatter in a visual studio project sorted my includes after which the pre compiled header was not the first include anymore.
In other words. If you have any of these:
#include "pch.h"
or
#include <stdio.h>
or
#include <iostream>
#include "stdafx.h"
Put it at the start of your file.
If your clang formatter is sorting the files automatically, try putting an enter after the pre compiled header. If it is on IBS_Preserve it will sort each #include block separately.
#include "pch.h" // must be first
#include "bar.h" // next block
#include "baz.h"
#include "foo.h"
More info at
Compiler Error C2065
A C++ identifier is a name used to identify a variable, function, class, module, or any other user-defined item. In C++ all names have to be declared before they are used. If you try to use the name of a such that hasn't been declared you will get an "undeclared identifier" compile-error.
According to the documentation, the declaration of printf() is in cstdio i.e. you have to include it, before using the function.
Another possible situation: accessing parent (a template class) member in a template class.
Fix method: using the parent class member by its full name (by prefixing this-> or parentClassName:: to the name of the member).
see: templates: parent class member variables not visible in inherited class
one more case where this issue can occur,
if(a==b)
double c;
getValue(c);
here, the value is declared in a condition and then used outside it.
It is like Using the function without declaring it. header file will contain the
function printf(). Include the header file in your program this is the solution for that.
Some user defined functions may also through error when not declared before using it. If
it is used globally no probs.
Most of the time, if you are very sure you imported the library in question, Visual Studio will guide you with IntelliSense.
Here is what worked for me:
Make sure that #include "stdafx.h" is declared first, that is, at the top of all of your includes.
Every undeclared variable in c error comes because the compiler is not able to find it in the project. One can include the external (header) file of the library in which the variable is defined. Hence in your question, you require <stdio.h>, that is a standard input output file, which describes printf(), functionality.
According to the documentation, the declaration of fprintf() is in i.e. you have to include it, before using the function.
Check if you are importing the same packages in your .m and in your .h
Example given: I had this very problem with the init method and it was caused by missing the "#import " on the .m file
Let's look at such piece of code:
#include <iostream>
int foo(int i) {return i; }
int foobar(int z) {return foo(z);}
int main() {
std::cout << foobar(3) << std::endl;
}
It compiles fine with g++ -std=c++11 ... and gives output 3. But The same output is given by:
#include <iostream>
int foo(int i) {return i; }
int foobar(int z) { foo(z);}
int main() {
std::cout << foobar(3) << std::endl;
}
It compiles without problems but clearly the keyword return is missed in foobar. Is it a bug in gcc 4.8.3 or maybe I'm not aware of some c++11 principle? (Runned on Fedora 20)
The C++ standard doesn't make a mandate for compilers to insist on a return-statement in functions return non-void. Instead, flowing off the end of such a function without a return-statement is undefined behavior. The relevant statement in the standard is in 6.6.3 [stmt.return] paragraph 2, last sentence (and in 3.6.1 [basic.start.main] paragraph 5 is the statement making it OK for main() to flow off this function):
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.
The primary reason for this approach is that it may be non-trivial or even impossible if the function actually ever really returns. Consider this function declaration and function definition:
extern void will_always_throw();
int does_not_return_anything() {
will_always_throw();
}
Assuming will_always_throw() indeed does as the name suggests, there is nothing wrong. In fact, if the compiler gets smarter and manages to verify that will_always_throw(), indeed, always throws (or a "noreturn" attribute is attached to will_always_throw(), it may warn about the last statement in this definition never being reached:
int does_return_something_just_in_case() {
will_always_throw();
return 17;
}
The general approach to deal with these situations is for compilers to support suitable options enabling/disabling warnings as necessary. For example, on your code all compilers I have access to (gcc, clang, and icc) create a warning assuming warnings are enable (using -Wall for the first two and -w2 for Intel's compiler).
The code compiles fine because it is well-formed, and so you can run it. But since this is undefined behavior, you cannot rely on any behavior of the program, anything is legal. To prevent accidents like this, enable compiler warnings. if you compile your code with -Wall, you will see
main.cpp:10:28: warning: no return statement in function returning non-void [-Wreturn-type]
int foobar(int z) { foo(z);}
Here you can get more information about those warnings. Use them and make sure your code compiles warning free. It can catch a lot of errors in your code at compile time.
What are undeclared identifier errors? What are common causes and how do I fix them?
Example error texts:
For the Visual Studio compiler: error C2065: 'cout' : undeclared identifier
For the GCC compiler: 'cout' undeclared (first use in this function)
They most often come from forgetting to include the header file that contains the function declaration, for example, this program will give an 'undeclared identifier' error:
Missing header
int main() {
std::cout << "Hello world!" << std::endl;
return 0;
}
To fix it, we must include the header:
#include <iostream>
int main() {
std::cout << "Hello world!" << std::endl;
return 0;
}
If you wrote the header and included it correctly, the header may contain the wrong include guard.
To read more, see http://msdn.microsoft.com/en-us/library/aa229215(v=vs.60).aspx.
Misspelled variable
Another common source of beginner's error occur when you misspelled a variable:
int main() {
int aComplicatedName;
AComplicatedName = 1; /* mind the uppercase A */
return 0;
}
Incorrect scope
For example, this code would give an error, because you need to use std::string:
#include <string>
int main() {
std::string s1 = "Hello"; // Correct.
string s2 = "world"; // WRONG - would give error.
}
Use before declaration
void f() { g(); }
void g() { }
g has not been declared before its first use. To fix it, either move the definition of g before f:
void g() { }
void f() { g(); }
Or add a declaration of g before f:
void g(); // declaration
void f() { g(); }
void g() { } // definition
stdafx.h not on top (VS-specific)
This is Visual Studio-specific. In VS, you need to add #include "stdafx.h" before any code. Code before it is ignored by the compiler, so if you have this:
#include <iostream>
#include "stdafx.h"
The #include <iostream> would be ignored. You need to move it below:
#include "stdafx.h"
#include <iostream>
Feel free to edit this answer.
Consider a similar situation in conversation. Imagine your friend says to you, "Bob is coming over for dinner," and you have no idea who Bob is. You're going to be confused, right? Your friend should have said, "I have a work colleague called Bob. Bob is coming over for dinner." Now Bob has been declared and you know who your friend is talking about.
The compiler emits an 'undeclared identifier' error when you have attempted to use some identifier (what would be the name of a function, variable, class, etc.) and the compiler has not seen a declaration for it. That is, the compiler has no idea what you are referring to because it hasn't seen it before.
If you get such an error in C or C++, it means that you haven't told the compiler about the thing you are trying to use. Declarations are often found in header files, so it likely means that you haven't included the appropriate header. Of course, it may be that you just haven't remembered to declare the entity at all.
Some compilers give more specific errors depending on the context. For example, attempting to compile X x; where the type X has not been declared with clang will tell you "unknown type name X". This is much more useful because you know it's trying to interpret X as a type. However, if you have int x = y;, where y is not yet declared, it will tell you "use of undeclared identifier y" because there is some ambiguity about what exactly y might represent.
In C and C++ all names have to be declared before they are used. If you try to use the name of a variable or a function that hasn't been declared you will get an "undeclared identifier" error.
However, functions are a special case in C (and in C only) in that you don't have to declare them first. The C compiler will the assume the function exists with the number and type of arguments as in the call. If the actual function definition does not match that you will get another error. This special case for functions does not exist in C++.
You fix these kind of errors by making sure that functions and variables are declared before they are used. In the case of printf you need to include the header file <stdio.h> (or <cstdio> in C++).
For standard functions, I recommend you check e.g. this reference site, and search for the functions you want to use. The documentation for each function tells you what header file you need.
I had the same problem with a custom class, which was defined in a namespace. I tried to use the class without the namespace, causing the compiler error "identifier "MyClass" is undefined".
Adding
using namespace <MyNamespace>
or using the class like
MyNamespace::MyClass myClass;
solved the problem.
These error meassages
1.For the Visual Studio compiler: error C2065: 'printf' : undeclared identifier
2.For the GCC compiler: `printf' undeclared (first use in this function)
mean that you use name printf but the compiler does not see where the name was declared and accordingly does not know what it means.
Any name used in a program shall be declared before its using. The compiler has to know what the name denotes.
In this particular case the compiler does not see the declaration of name printf . As we know (but not the compiler) it is the name of standard C function declared in header <stdio.h> in C or in header <cstdio> in C++ and placed in standard (std::) and global (::) (not necessarily) name spaces.
So before using this function we have to provide its name declaration to the compiler by including corresponding headers.
For example
C:
#include <stdio.h>
int main( void )
{
printf( "Hello World\n" );
}
C++:
#include <cstdio>
int main()
{
std::printf( "Hello World\n" );
// or printf( "Hello World\n" );
// or ::printf( "Hello World\n" );
}
Sometimes the reason of such an error is a simple typo. For example let's assume that you defined function PrintHello
void PrintHello()
{
std::printf( "Hello World\n" );
}
but in main you made a typo and instead of PrintHello you typed printHello with lower case letter 'p'.
#include <cstdio>
void PrintHello()
{
std::printf( "Hello World\n" );
}
int main()
{
printHello();
}
In this case the compiler will issue such an error because it does not see the declaration of name printHello. PrintHello and printHello are two different names one of which was declared and other was not declared but used in the body of main
It happened to me when the auto formatter in a visual studio project sorted my includes after which the pre compiled header was not the first include anymore.
In other words. If you have any of these:
#include "pch.h"
or
#include <stdio.h>
or
#include <iostream>
#include "stdafx.h"
Put it at the start of your file.
If your clang formatter is sorting the files automatically, try putting an enter after the pre compiled header. If it is on IBS_Preserve it will sort each #include block separately.
#include "pch.h" // must be first
#include "bar.h" // next block
#include "baz.h"
#include "foo.h"
More info at
Compiler Error C2065
A C++ identifier is a name used to identify a variable, function, class, module, or any other user-defined item. In C++ all names have to be declared before they are used. If you try to use the name of a such that hasn't been declared you will get an "undeclared identifier" compile-error.
According to the documentation, the declaration of printf() is in cstdio i.e. you have to include it, before using the function.
Another possible situation: accessing parent (a template class) member in a template class.
Fix method: using the parent class member by its full name (by prefixing this-> or parentClassName:: to the name of the member).
see: templates: parent class member variables not visible in inherited class
one more case where this issue can occur,
if(a==b)
double c;
getValue(c);
here, the value is declared in a condition and then used outside it.
It is like Using the function without declaring it. header file will contain the
function printf(). Include the header file in your program this is the solution for that.
Some user defined functions may also through error when not declared before using it. If
it is used globally no probs.
Most of the time, if you are very sure you imported the library in question, Visual Studio will guide you with IntelliSense.
Here is what worked for me:
Make sure that #include "stdafx.h" is declared first, that is, at the top of all of your includes.
Every undeclared variable in c error comes because the compiler is not able to find it in the project. One can include the external (header) file of the library in which the variable is defined. Hence in your question, you require <stdio.h>, that is a standard input output file, which describes printf(), functionality.
According to the documentation, the declaration of fprintf() is in i.e. you have to include it, before using the function.
Check if you are importing the same packages in your .m and in your .h
Example given: I had this very problem with the init method and it was caused by missing the "#import " on the .m file
I am a fairly experienced .net developer but new to Arduino and C/C++ and I am trying to create my first library which is a simple driver for a 7 segment led display. I have many obtuse compiler errors but in the spirit of one thing at a time this is the first. I want to add a parameterless constructor to my class and when I do library compiles fine but when I try to use the class in a sketch the compiler gives me the rather obtuse "request for member 'setDigit' in 'sevenSegmentLed', which is of non-class type 'SevenSegmentLed()"
The simplest example code is below:
#ifndef SevenSegmentLed_h
#define SevenSegmentLed_h
#include "Arduino.h"
class SevenSegmentLed
{
public:
void setDigit(int digit);
SevenSegmentLed();
};
#endif
#include "Arduino.h"
#include "SevenSegmentLed.h"
SevenSegmentLed::SevenSegmentLed()
{
}
void SevenSegmentLed::setDigit(int digit)
{
}
#include "SevenSegmentLed.h"
SevenSegmentLed sevenSegmentLed();
void setup() {
sevenSegmentLed.setDigit(4);
}
void loop() {
// put your main code here, to run repeatedly:
}
However if I change the constructor signature to: SevenSegmentLed(int wtf); and instantiate it thus: SevenSegmentLed sevenSegmentLed(1); it compiles just fine. So as the parameter says, WTF?
I believe the issue is that this:
SevenSegmentLed sevenSegmentLed();
Is interpreted as a function declaration and not an initialization. Note that you can't have this problem with c# because you have the new keyword disambiguating for you so this particular problem is avoided.
To fix you can do 2 things:
Use the c++ uniform initialization syntax (introduced in newer c++ standard to avoid exactly your issue):
SevenSegmentLed sevenSegmentLed{};
Or use the following syntax:
SevenSegmentLed sevenSegmentLed;
The main benefit of the uniform syntax is that it's uniform. So for example if you have a constructor that takes an integer you can write it like this:
SevenSegmentLed sevenSegmentLed{1};
Generally speaking the uniform initialization syntax is preferable, when I was writing the c++ guideline at my work (mostly c# and php guys) I decided to go with this as it's the most clear and unambiguous.