Why does this VC++ program not compile? - visual-c++

This came up in a class recently. The problem is the first occurrence of "ptr" in the if. The error is "expression must be a modifiable value".
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int * ptr = nullptr;
int i = 7;
if (ptr == nullptr && ptr = &i)
cout << *ptr;
return 0;
}

Parentheses are your friend. The C/C++ operator precedence table is deep and some aspects are not intuitive.
In this case, logical AND (&&) binds tighter than assignment (=). ("Binds tighter" == "is of higher precedence".)
When in doubt, I always use a quick google search for "c operator precedence table" to get a bunch of result pages all of which provide a helpful table in order of precedence. (Actually, when in doubt in my own code I always just add the parentheses in the first place.)

Related

How to use parameter in exe

I want to use parameters in a program I made in C/C++ languages. Example:
MaxPayne2.exe -developer -developerkeys
I want to use a parameter like this in my exe file. How can I do it?
https://en.cppreference.com/w/cpp/language/main_function
While I would usually recommend adding more context this is your answer.
The standard c++ main has two additional parameters,
int main (int argc, char *argv[]) { }
To use these "arguments" (as they are called) you just reference their point in the argv array.
argc = the number of additional arguments supplied.
argv = the array of argument values supplied.
Example:
int main (int argc, char *argv[])
{
cout << argv[argc-1]; //Prints out the last argument supplied.
}
(note)If my syntax is wrong someone please correct me, my c++ is a bit rusty.

Would argc ever be passed less than 1

I'm developing my own version of getopt() in assembly and trying to get my head wrapped around this snippet, specifically line 476
if (argc < 1)
return -1;
As the normal calling convention would be something like this;
int c = getopt( argc, argv, "vm:drx:");
and assuming the programmer hasn't done anything with argc before hand, the only reason I can think it would be there is that some flavor of Linux, possibly non POSIX compliant would'nt pass argv[0] application path & name. Therefore, argc could be zero. Is there any credence to this conjecture?
Of the 12 times this variable is used in this procedure, it's only ever asserted or copied, never modified and not referenced at all in the two levels of procedure before this.
Consider this:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
execve("./testargc", NULL, NULL);
}
And this program:
#include <stdio.h>
int main (int argc, char* argv[])
{
printf("%d\n", argc);
}
The first one execs the 2nd one with no arguments. The pathname is not passed in and as a result argc is 0.

C++11: how to use accumulate / lambda function to calculate the sum of all sizes from a vector of string?

For a vector of strings, return the sum of each string's size.
I tried to use accumulate, together with a lambda function (Is it the best way of calculating what I want in 1-line?)
Codes are written in wandbox (https://wandbox.org/permlink/YAqXGiwxuGVZkDPT)
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> v = {"abc", "def", "ghi"};
size_t totalSize = accumulate(v.begin(), v.end(), [](string s){return s.size();});
cout << totalSize << endl;
return 0;
}
I expect to get a number (9), however, errors are returned:
/opt/wandbox/gcc-head/include/c++/10.0.0/bits/stl_numeric.h:135:39: note: 'std::__cxx11::basic_string' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
135 | __init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
I want to know how to fix my codes? Thanks.
That's because you do not use std::accumulate properly. Namely, you 1) did not specify the initial value and 2) provided unary predicate instead of a binary. Please check the docs.
The proper way to write what you want would be:
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> v = {"abc", "def", "ghi"};
size_t totalSize = accumulate(v.begin(), v.end(), 0,
[](size_t sum, const std::string& str){ return sum + str.size(); });
cout << totalSize << endl;
return 0;
}
Both issues are fixed in this code:
0 is specified as initial value, because std::accumulate needs to know where to start, and
The lambda now accepts two parameters: accumulated value, and the next element.
Also note how std::string is passed by const ref into the lambda, while you passed it by value, which was leading to string copy on each invocation, which is not cool

How to to get custom return value from system()

I need to pass 1 value between programs. In my case, I run (VERY SIMPLE) program within another by calling system("SimpleProgram").
Is there a way how to pass 1 value (integer) returned by SimpleProgram. Neither "return 123" nor "exit(123)" doesnt work.
Is there any elegant way to pass such value? (I dont want to write and read an external file)
EDIT:
The language is C++, the programming is done on BeagleBone with Angstrom distribution.
retCode = system("cd /home/martin/uart/temp/xml_parser && ./xmldom");
Note what the man page for system(3) says about the return code:
The value returned is -1 on error (e.g. fork(2) failed), and the
return status of the command otherwise.
This latter return status is in the format specified in wait(2). Thus, the exit code of the command will
be WEXITSTATUS(status).
So you're almost there. If you have a simple program that returns 123, as you stated:
int main(int argc, char **argv) {
return 123;
}
then you can run it with system(3) and see its return code by using WEXITSTATUS():
#include <iostream>
using namespace std;
#include <stdlib.h>
int main(int argc, char **argv) {
int rc = system(argv[1]);
cout << WEXITSTATUS(rc) << '\n';
}
Naming the first program return123 and the second system:
$ ./system ./return123
123
If you leave off the WEXITSTATUS() and just print rc directly, you will get an incorrect value.
The standard way to do this is with UNIX pipes.
If it's just a hack, you might as well just use the binary return value, but in either case, you'd have to use execve() instead of system().

How to change the name of a haskell process under linux

I am trying to change the name of a running process under linux. In C, I would just modify argv[0] in-place, but how can I do that from haskell? I noticed that ghc has a primitive called getProgArgv:
foreign import ccall unsafe "getProgArgv"
getProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO ()
but I tried with that and it didn't work. Also, I am aware of prctl(PR_SET_NAME,"...") but that only changes the current thread's name, and most tools (such as ps and htop) do not use that name.
Ok, so I came up with an ugly hack that seems to work. It based on a idea borrowed from here. We have to use an auxiliary c file:
#include <string.h>
#include <sys/prctl.h>
char *argv0 = 0;
static void capture_argv0(int argc, char *argv[]) {
argv0 = argv[0];
}
__attribute__((section(".init_array"))) void (*p_capture_argv0)(int, char*[]) = &capture_argv0;
void set_prog_name(char *name) {
if (!argv0) return;
size_t len = strlen(argv0);
strncpy(argv0, name, len);
prctl(PR_SET_NAME, name);
}
This relies on the section(".init_array") attribute that tells gcc to register capture_argv0 as an initialization function. This means that it will be executed before main. We use it to make a copy of the argv[0] pointer and store it as a global variable. Now we can call set_prog_name from haskell.

Resources