C++ Expected string literal before args - c++

#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
string argstr[argc];
for(int c = 1; c++; c<argc) {
argstr[c].assign(argv[c]);
}
for(int c = 1; c++; c<argc) {
__asm__(argstr[c]); //This is where the error occurs
cout << argstr[c] << endl;
}
}
If I try to compile it with MinGW, I get the following error:
Main.cpp: In function 'int main(int, char**)':
Main.cpp:15:6: error: expected string-literal before 'args'
asm(args);
I know this, that's why I assign the arguments to a vector of strings.

__asm__() is a compile-time construct. The argument must be a string literal, and not a variable.

You can't dynamically execute assembly code like this. The compiler needs to know about the assembly instructions at compile time so it can check if they are valid, but you are trying to pass them in at run time.
Edit: One workaround is to write a wrapper program in python (for example) that injects a string literal into your C++ __asm__ construct and then compiles it and executes it for you.

Related

C++ error two or more data types in declaration of variable

I ran the following C program and got In as the output.
#include<stdio.h>
int main()
{
auto int i = 0;
if(++i)
printf("In");
else
printf("Out");
return 0;
}
But when I tried to run it as a C++ program by changing the header files and standard output, I got an error:
jdoodle.cpp: In function ‘int main()’:
jdoodle.cpp:6:14: error: two or more data types in declaration of ‘i'.
6 | auto int i = 0;
| ^.
jdoodle.cpp:7:10: error: ‘i’ was not declared in this scope.
7 | if(++i).
| ^
C++ code:
#include <iostream>
using namespace std;
int main() {
auto int i = 0;
if(++i)
cout<<"In";
else
cout<<"Out";
return 0;
}
In C, auto is an obsolete keyword it inherited from B. It is either implicitly assumed, or illegal to specify. So, it's basically never used.
C++ inherited this keyword from C as is, and your code would have compiled under C++98. In C++11 this keyword was repurposed to be used for implicit type deduction. It is now widely used but means something completely different and the way you tried to use it is illegal.
The point is, C and C++ are different languages. Writing code that compiles under C and C++ is difficult and requires care.
In the C++ program, for the line
auto int i = 0;
the auto keyword is being used to automatically deduce the type of variable i from its initialized value if compiling with C++11 or later. However, the line also includes int, which is also declaring the type. You can't use both of them -- you get the same error if you write double int i = 0; (i can't be both a double and an int) or int int i = 0; (it's the same type but you're declaring the type twice). Choose one or the other, i.e. either
auto i = 0;
or
int i = 0;
You can see that it works with C++98 but not C++11 or C++14 online here. Prior to C++11 the auto keyword was a storage class specifier.

Proper array type for execvp

I'm having difficulty figuring out exactly how to use execvp in C++. I'm not having any issues getting my code to work, but I'm specifically trying to figure out how to do it in a way that doesn't make the compiler complain.
I have looked at various questions on Stack Overflow and other resources, but I have been unable to find a solution that results in zero warnings from the compiler.
Consider the following C++ program, which prints its own source code:
#include <unistd.h>
int main(int argc, char *argv[])
{
char *args[3];
args[0] = "/bin/cat";
args[1] = __FILE__;
args[2] = NULL;
execvp(args[0], args);
return 0;
}
(I know that the return 0 should never be reached; I'm not so concerned with error handling in this question.)
When I compile it, the compiler emits two warnings:
$ g++ -Wall exec.cpp
exec.cpp: In function ‘int main(int, char**)’:
exec.cpp:6:15: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
args[0] = "/bin/cat";
^~~~~~~~~~
exec.cpp:7:15: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
args[1] = __FILE__;
^~~~~~~~
The compiled program successfully prints the source file. However, I'd really like to get the program to compile without any warnings. Since the compiler doesn't like that the string literals are being assigned to a pointer of type char* (not const char*), I suppose it would make sense to mark args as an array of const char* pointers. Consider this version of the program:
#include <unistd.h>
int main(int argc, char *argv[])
{
const char *args[3];
args[0] = "/bin/cat";
args[1] = __FILE__;
args[2] = NULL;
execvp(args[0], args);
return 0;
}
I would think that this program should compile and run with no warnings or errors, but the compiler does emit an error:
$ g++ -Wall exec.cpp
exec.cpp: In function ‘int main(int, char**)’:
exec.cpp:10:25: error: invalid conversion from ‘const char**’ to ‘char* const*’ [-fpermissive]
execvp(args[0], args);
^
In file included from exec.cpp:1:0:
/usr/include/unistd.h:581:12: note: initializing argument 2 of ‘int execvp(const char*, char* const*)’
extern int execvp (const char *__file, char *const __argv[])
^~~~~~
I also tried declaring args as char const *args[3], but the compiler emits the same error. The only way I am able to get it to compile with no warnings is by casting args in the call to execvp:
const char *args[3];
...
execvp(args[0], (char* const*)args);
This version compiles without warnings and runs successfully. However, I prefer to avoid casting when I can, because it makes it harder for me to reason about the type conversions going on.
Are one of the two working ways that I have shown above the best way to create an argument array to pass to execvp, or is there a better way that is clear and does not result in the compiler complaining?
I am using two different compilers - g++ 6.2.0 for native compilation on Ubuntu x86_64, and g++ 4.5.3 for cross compilation to an ARM platform.
Edit:
I do not believe that my question is a duplicate of this question. I understand the different effects of using const in different ways with respect to a char* variable. I am specifically asking which type is conventionally used for execvp calls, which is not answered by the linked question.

Random number is returned

The following code :
#include <iostream>
using namespace std;
int test()
{
cout<<"question \n";
return 0;
}
int main(){
cout<<test;
}
Output:
question
1
The following code gives 1 everytime I run but I am expecting the output to be 0.
Whereas when I replace the test by test() then I get the expected output. Not sure why is this happening. Please suggest and comment if any rule behind it.
C++ always requires you to use parentheses to call functions. If you omit them, it thinks you want to know the address of the function instead of calling it. The address is then considered to be a (truthy) boolean and gets output as 1. This warning (from gcc -Wall) explains it well:
x.cpp: In function ‘int main()’:
x.cpp:9:11: warning: the address of ‘int test()’ will always evaluate as ‘true’ [-Waddress]
cout<<test;
^
std::cout << test;
Outputs 1 because test is a function pointer, it will be converted to bool with std::cout.

GCC cannot compile: '* does not name a type'

Today, after Slackware 13.37 installation, i've got the problem: default GCC 4.5.2 cannot compile my code. Now I study C++ by the Stephen Davis's book "C++ for dummies" and want to compile this:
#include <stdio.h>
#include <iostream.h>
int main(int nNumberofArgs, char* pszArgs[])
{
int nNCelsius;
cout << "Celsisus: ";
cin >> nNCelsius;
int nNFactor;
nNFactor = 212 - 32;
int nFahrenheit;
nFahrenheit = nNFactor * nNCelsius / 100 + 32;
cout << "Fahrenheit: ";
cout << nFahrenheit;
return 0;
}
But my GCC 4.5.2 gives these errors:
FahTCel.cpp:7:14: error: expected ')' before ';' token
FahTCel.cpp:7:14: error: 'main' declared as function returning a function
FahTCel.cpp:8:1: error: 'cout' does not name a type
FahTCel.cpp:9:1: error: 'cin' does not name a type
FahTCel.cpp:12:1: error: 'nNFactor' does not name a type
FahTCel.cpp:15:1: error: 'nFahrenheit' does not name a type
FahTCel.cpp:17:1: error: 'cout' does not name a type
FahTCel.cpp:18:1: error: 'cout' does not name a type
FahTCel.cpp:20:1: error: expected unqualified-id before 'return'
FahTCel.cpp:21:1: error: expected declaration before '}' token
Three errors:
The correct header is <iostream>. This program requires no other headers.
You must either put using namespace std; in the file, or refer to std::cout and std::cin explicitly. Take your pick, plenty of C++ programmers disagree about which of the two options is better. (You could also bring just cin and cout into your namespace, if you wanted.)
The program does not write a line terminator at the end. This will cause the output to "look bad" on most terminals, with the command prompt appearing on the same line as the output. For example:
Here are the corrections:
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
...
cout << nFahrenheit << '\n';
...
}
Note: It is extremely unusual to see main take parameters with names other than argc and argv. Changing the names just makes it harder for other people to read your code.
its std::cout or you should add using namespace std;
and the include should be < iostream> not < ionstream.h>.

How pass vector<int> to pthread_create correctly in C++?

I would like to create a thread passing a vector as parameter.
but i got the following errors:
error: invalid conversion from ‘int’ to ‘void* (*)(void*)’ [-fpermissive]
error: initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’ [-fpermissive]
I have the following code:
#include <iostream>
#include <vector>
#include <pthread.h>
using namespace std;
void* func(void* args)
{
vector<int>* v = static_cast<vector<int>*>(args);
cout << "Vector size: " << v->size();
}
int main ( int argc, char* argv[] )
{
vector<int> integers;
pthread_t thread;
for ( int i = 0; i < 10; i++)
integers.push_back(i+1);
// overheat call
//pthread_create( &thread, NULL, func, static_cast<void*>(&integers));
pthread_create( &thread, NULL,func,&integers);
cout << "Main thread finalized" << endl;
return 0;
}
How I can do it properly ?
Thanks
EDIT: forgot the includes posting here only; Revised.
I got new errors:
error: stray ‘\305’ in program
error: stray ‘\231’ in program
I am trying to know about it.
Thanks in advance.
FINAL EDIT : Thanks to all. Sorry, I had another int var called func in other location.
Thanks for your help.
You have forgotten to include <vector>; this confuses the compiler as it first fails to generate func, and then fails to identify it as a function in the call to pthread_create.
Once you include that, your code should compile (and you can remove the static_cast<void*> if you like); but to work correctly you also need to call pthread_join before the vector goes out of scope, and return a value from func.
UPDATE: your latest edit has broken the code: you should not cast func to void*, but leave it as a function pointer. This should work:
pthread_create(&thread, NULL, func, &integers);
Errors like stray ‘\305’ in program imply that you have some strange characters in your code, although they're not in the code you've posted. Have a look at the lines that the error messages refer to.