I have following program:
#include <stdio.h>
int main(int args, char *argv[]) {
printf("%f\n", 0.99999);
printf("%e\n", 0.99999);
}
The result is:
0.009990
9.999900e-001
Why is the first number wrong? I use Windows XP, compiler "Logiciels Informatique lcc-win32 version 3.8. Compilation date: Nov 30 2012 19:38:03".
That program is correct, and its output should be:
0.999990
9.999900e-01
or something very similar to that.
(You don't use args or argv, and the usual name for the first parameter of main is argc rather than args, but neither of those is a problem that should affect your program's behavior.)
It looks like you've found a bug in your implementation, probably in the runtime library rather than in the compiler itself. My brief Google searches haven't turned up a reference to this particular bug (in fact, the top hit was this question).
I suggest contacting the maintainer of lcc-win; contact information is on the web site. A short description and a link to this question should provide enough information, at least to start.
Related
*** EDIT - I know it is a long post and I know I have used some 'interesting' language choices. And, I'm choosing to believe the three answers I've had so far were made with good intent - for that I thank you. But, I really must insist, if you are not willing to read the whole post thoroughly or if you don't understand what it is I am actually asking, please save both our time and refrain from posting. ***
I have been searching for an answer to exactly the same question posed here - same online course, same lecturer; I recognise the code from the video.
I quickly found solutions in the form of #define and using an enum, but that still didn't really solve how the lecturer got his code to compile; and, I would like to actually comprehend, not just make it work so, I tried to dig deeper.
The professor in question doesn't ever actually show the code compilation, it's always a "here's one I compiled earlier" scenario - so I had included the possibility the error was in that unseen stage as indicated by the two answers on the page: he may well have been using g++ or clang.
However, my search was most circuitous, leading me hither and tither across the net, and in my quest, before I came across the above linked answers and amongst other things I came across this video where at around the 9 minute mark he compiles this code:
#include <stdio.h>
#include <stdlib.h>
const int ARRAY_LENGTH = 5;
void printarray(int myarray[ARRAY_LENGTH]) {
for (int i = 0; i < ARRAY_LENGTH; i++){
printf("%i, ", myarray[i]);
}
printf("\n");
}
int main (int argc, char **argv){
int a[ARRAY_LENGTH] = {1, 2, 3, 4, 5};
int b[ARRAY_LENGTH] = {5, 4, 3, 2, 1};
int *p = malloc(sizeof(int) * 567);
printarray(a);
printarray(b);
printarray(p);
free(p);
}
He uses a makefile that runs gcc with the -g -Wall flags and is on a mac (I think, please correct me if I am wrong). The internet tells me clang is the default compiler on macs, so maybe this is something to do with it (although I have no idea why that would be), but trying this code with g++ gives error: invalid conversion from ‘void*’ to ‘int*’ [-fpermissive].
I would just like to understand what is actually going on. Not that consts in C aren't actually constant, more like read-only; use #define/enum. I've read that (probably on here), I've understood it, I've re-written my code and successfully compiled using both methodologies. I've even compiled using const by separating the declaration and assignment. And, at this point, it's not about how the original lecturer compiled his code anymore - I've tested g++ it definitely works, and, if I'd have found that answer earlier I would probably be happily satisfied now with no further questions.
But, I didn't. And, none of what I've found explains how the code from the video compiled and ran (or, why multiple people think this is good practice C coding that should be shared as educational material, but that seems a secondary digression). Maybe its a simple typo, but I've checked and re-checked and I simply cannot find it. Hopefully, someone will be able to adequately put an end to the mystery that plagues me.
Thank you for your time in reading, it seems a bit long but I was trying to be thorough and avoid the all too common initial question-answer ping-pong. No doubt I have still neglected something of the utmost import - c'est la vie.
This is a result of constant folding in the clang compiler.
The instructor is compiling the program on a Mac, and on that platform "gcc" is an alias for "clang". While gcc does not perform this folding for a VLA, clang does.
From the clang documentation (version 10):
Differences between all c* and gnu* modes:
c* modes define __STRICT_ANSI__.
Target-specific defines not prefixed by underscores, like “linux”, are defined in gnu* modes.
Trigraphs default to being off in gnu* modes; they can be enabled by the -trigraphs option.
The parser recognizes asm and typeof as keywords in gnu* modes; the variants __asm__ and __typeof__ are recognized in all modes.
The Apple “blocks” extension is recognized by default in gnu* modes on some platforms; it can be enabled in any mode with the -fblocks
option.
Arrays that are VLA’s according to the standard, but which can be constant folded by the frontend are treated as fixed size arrays. This
occurs for things like int X[(1, 2)];, which is technically a VLA. c *
modes are strictly compliant and treat these as VLAs.
Is environ variable (as of POSIX) available (at least for reading) in major Windows C compilers?
I know that execve is available on Windows: https://en.wikipedia.org/wiki/Exec_(system_call)
But I am unsure if environ is available, too.
environ should be available, but is deprecated and you should use the more secure methods.
The execXX() calls are available, but fork() isn't, so effectively the exec functions are rendered useless.
You can use CreateProcessA for similar effect, and have the ability to set up environments and pipes cleanly.
Just to acknowledge #eryksun 's concerns: You do need to consider which character set you are using before using any Microsoft "A" file (and other O/S) APIs. It is simplest if you can do all your code using 16bit unicode, as that is the underlying type for NT, Windows 7, Windows 10. On unix and mac, you can make assumptions that utf-8 is the 8-bit character set of choice, but that has yet to happen for windows, and of course "backward compatibility". If you are using any of the "unix-like" M/S API, you should already be making the same design decisions, though, so should already have an answer.
The following program will print the environment variables.
#include <stdio.h>
int main(int argc, char *argv[], char *env[]){
int e = 0;
while (env[e] != NULL) {
printf("%s\n", env[e++]);
}
}
EDIT: I was wrong; looks like the MSVC runtime library does include support for environ (though deprecated) after all. I will leave my previous answer below if anyone is interested in alternative methods.
Not that I'm aware of, but, if you want to access the environment-variables on Windows, you have some options:
Declare main or wmain with the following signature:
int (w)main(int argc, char/wchar_t *argv[], char/wchar_t *envp[])
This is defined in the C Standard as a pointer to the environment block, if applicable:
§ J.5.1:
In a hosted environment, the main function receives a third argument, char *envp[],
that points to a null-terminated array of pointers to char, each of which points to a string
that provides information about the environment for this execution of the program
(5.1.2.2.1).
Use the Windows API function GetEnvironmentVariable(A|W) to get an individual environment variable, or GetEnvironmentStrings to get the entire environment array.
The standard C function getenv.
What is wrong with this code?
#include <stdio.h>
#include <stdarg.h>
void myprintf(const char * format, ...) __printflike(1, 2);
int main(int argc, const char * argv[]) {
printf("%s\n");
myprintf("%s\n");
return 0;
}
void myprintf(const char * format, ...) {
if (format) {
va_list arguments;
va_start(arguments, format);
vprintf(format, arguments);
va_end(arguments);
}
}
By using __printflike I get a nice warning, like printf. But unlike printf, which prints trash at least, I get EXC_BAD_ACCESS on the call to vprintf as shown here:
Is there any way I can make this work?
Thanks!
UPDATE: I understand that by calling a function with the wrong number of arguments I get undefined behavior, but I'd like myprintf to behave just like printf does (without crashing). Is that possible? Is there any way I can check the arguments before calling vprintf to avoid the exception?
UPDATE 2: I think I got it now, thanks for all the comments and answers. For this very simple example I think is better to use a macro, which fails fast and crashes at the calling point:
Undefined means unpredictable. In one run printf may produce trash, in another it may produce EXC_BAD_ACCESS instead. You cannot reproduce undefined behavior. In this particular case, the %s term in the formatting string says printf need to find a C-string. Depending on your libc implementation, when you did not specify the second argument, it may find it somewhere. And if it happens that a null character is found not far away from this pointer, you get trash output. If not, printf will continue to search the end of the string until it gets out of range of the memory assigned to your program and you get the EXC_BAD_ACCESS.
It is not possible - at least not in a portable way - to determine how many arguments are passed to a function. The format specifier is the only way for printf to determine how many values are to be popped from the stack so entering a wrong format specifier gives you undefined behavior. It is just one of those C things you need to learn and then move on.
By trying to "correct" something like this you may just make the code more unreadable and hard for other people to understand.
Is there any way I can check the arguments before calling vprintf to avoid the exception?
Just one: Take the compiler's warning serious and eliminate your programming bug that the warning points you to.
See: It's becoming winter now, it will have mud and snow on the streets (in Europe at least), so you have your preferred garage mount the winter tires to your Porsche. On return of this nice car you find the following sticker on the dashboard (put there by the garage):
(apx 100 miles/h)
This sticker reminds you, that the freshly mounted winter tires do not support the maximum speed of the car.
You wouldn't drive faster now expecting the car to stop the moment the tires are about to break, won't you?
It's up to you, the driver to respect this warning!
;-)
What is considered best practice when referring to a program's name? I've seen:
#define PROGRAM_NAME "myprog"
printf("this is %s\n", PROGRAM_NAME);
as well as:
printf("this is %s\n", argv[0]);
I know, that the second approach will give me ./myprog rather than myprog when the program is not called from $PATH and that the first approach will guarantee consistence regarding the program's name.
But is there anything else, that makes one approach superior to the other?
The second approach is superior when you have multiple links. In *nix systems, sometimes behavior depends on how you call a program. So hard coding the program name would clearly be a problem -- it could never check that.
I tried to take the best of both worlds:
char const * program_name;
int main(int argc, char **argv) {
program_name = argv[0];
//...
}
If you need program_name to be available in some other file you can declare it like this:
extern char const * program_name;
I declare "char const *" because I want it to be a pointer which points to const data. I'm not sure if I did right this part.
I usually use argv[0], or basename(argv[0]) if possible. From the user's POV, I think if they rename or hardlink an executable (or somebody else does that for them), then they want messages from it to appear under the name they're using, not under some other name it was compiled as, that they may or may not know about.
Similarly if you discover in future that you want to compile your program under different names with different options, to give different versions, do you want to wrap an #ifndef around that #define and make sure that it's defined via the compiler command line: -DPROGRAM_NAME=myprog_demo, or do you just want to do it and it works?
The exception might be that if your usage instructions are an extract from a manpage or other documentation, then possibly you do want to hardwire the program name into that. But then you probably wouldn't use the #define either.
Implementations needn't provide argv[0], though, so for best portable practices handle that case too. Then again, if your system doesn't provide it then probably the user isn't actually going to see messages on any kind of terminal, either.
By the way:
#define PROGRAM_NAME "myprog"
puts("this is " PROGRAM_NAME);
The second approach could give you also strings like /usr/bin/myprog if you executed it that way; basename should give the name of the executable (that you could think of as the name of your program)... unless it is symlinked... (in that case, you have the name of the link... that could be used to do choices of some kind in the program behaviour).
The first approach "fixes" the program name to what the programmer wanted, no matter how the user renamed the executable file or symlinked (or even hardlinked)
It doesn't exactly answer your question for programming best practices, but I think you should also keep in mind what's best for the user.
I personally prefer programs refering to themselves using argv[0], i.e. the command I was calling, and not some random name that the coder hardcoded in the program. A few examples where a hardcoded name is annoying or at least not helpful:
I've created a link to a program
I've renamed the binary for some reason
I have multiple executables with the same basenames in different directories in my $PATH
A program gives me hints about other ways to call it, e.g. in "usage" messages
The only situation where I'd prefer a hardcoded program name is when I'm using GUI applications. I wouldn't want to see "~/foo/bar.pl" as a window title.
The former is superior to the later when your don't have argv at hand.
#define PROGRAM_NAME "myprog"
void salute()
{
// no argv available
printf("Hello from %s\n", PROGRAM_NAME );
}
void main( int argc, char** argv )
{
salute();
}
Depends whether argv is in scope or not...
Is there any way to access the command line arguments, without using the argument to main? I need to access it in another function, and I would prefer not passing it in.
I need a solution that only necessarily works on Mac OS and Linux with GCC.
I don't know how to do it on MacOS, but I suspect the trick I will describe here can be ported to MacOS with a bit of cross-reading.
On linux you can use the so called ".init_array" section of the ELF binary, to register a function which gets called during program initilization (before main() is called). This function has the same signature as the normal main() function, execept it returns "void".
Thus, you can use this function to remember or process argc, argv[] and evp[].
Here is some code you can use:
static void my_cool_main(int argc, char* argv[], char* envp[])
{
// your code goes here
}
__attribute__((section(".init_array"))) void (* p_my_cool_main)(int,char*[],char*[]) = &my_cool_main;
PS: This code can also be put in a library, so it should fit your case.
It even works, when your prgram is run with valgrind - valgrind does not fork a new process, and this results in /proc/self/cmdline showing the original valgrind command-line.
PPS: Keep in mind that during this very early program execution many subsystem are not yet fully initialized - I tried libc I/O routines, they seem to work, but don't rely on it - even gloval variables might not yet be constructed, etc...
In Linux, you can open /proc/self/cmdline (assuming that /proc is present) and parse manually (this is only required if you need argc/argv before main() - e.g. in a global constructor - as otherwise it's better to pass them via global vars).
More solutions are available here: http://blog.linuxgamepublishing.com/2009/10/12/argv-and-argc-and-just-how-to-get-them/
Yeah, it's gross and unportable, but if you are solving practical problems you may not care.
You can copy them into global variables if you want.
I do not think you should do it as the C runtime will prepare the arguments and pass it into the main via int argc, char **argv, do not attempt to manipulate the behaviour by hacking it up as it would largely be unportable or possibly undefined behaviour!! Stick to the rules and you will have portability...no other way of doing it other than breaking it...
You can. Most platforms provide global variables __argc and __argv. But again, I support zneak's comment.
P.S. Use boost::program_options to parse them. Please do not do it any other way in C++.
Is there some reason why passing a pointer to space that is already consumed is so bad? You won't be getting any real savings out of eliminating the argument to the function in question and you could set off an interesting display of fireworks. Skirting around main()'s call stack with creative hackery usually ends up in undefined behavior, or reliance on compiler specific behavior. Both are bad for functionality and portability respectively.
Keep in mind the arguments in question are pointers to arguments, they are going to consume space no matter what you do. The convenience of an index of them is as cheap as sizeof(int), I don't see any reason not to use it.
It sounds like you are optimizing rather aggressively and prematurely, or you are stuck with having to add features into code that you really don't want to mess with. In either case, doing things conventionally will save both time and trouble.