I am trying to implement the code given in this page
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366062%28v=vs.85%29.aspx
I am using mingw (gcc) to compile this.
But the following lines cannot be compiled. I have included 'time.h'. I searched but cannot locate this '_localtime31_s' or its equivalent in gcc.
error = _localtime32_s(&newtime, (__time32_t*) &pAdapter->LeaseObtained);
error = asctime_s(buffer, 32, &newtime);
Where is the time functions here?
Thanks
The functions localtime_s and asctime_s are Microsoft-specific extensions, provided by (certain versions of) the MS runtime library. This is provided by the MS header files. Since those are copyright MS and not allowed for free distribution, mingw provides its own versions of headers - and these probably don't contain these extensions (they certainly didn't a while back when I was using mingw on my local machine - my main machine these days runs Linux...).
Note that casting the time value to time32_t * is probably a bad idea - it is almost certainly going to bite you if you ever compile your code with a time_t that isn't a 32-bit value.
The localtime_r function is a semi-standard version that could be used instead of localtime_s (you will need to pay attention to 32 vs 64-bit time values). You can certainly also use localtime (aside from having to turn off MS's annoying "this function is not safe, please use ..._s instead" - I don't REALLY want to convert my 100 uses of strcpy to strcpy_s that work perfectly fine because it has already been checked elsewhere).
Similarly there is asctime_r which provides a re-entrant version.
You could, perhaps, also add the prototypes for these functions to your file somewhere, I believe that would, as long as you are compiling for Windows, solve the problem:
Link to MS function documentation: localtime_s and asctime_s.
MinGW-w64 provides an option to enable the secure CRT functions. Note there are compatibility issues with Windows XP, where msvcrt.dll does not contain these functions and your application will not work in that environment.
These are standardized in C11 Annex K, which is optional and may be missing on C11 conformant systems.
Related
Lately I'm diving into optimizing my C++ code and as such started to play around with the compiler explorer. Since i am mainly developing on windows with Visual Studio i used the msvc compiler.
At some point msvc got out of hand. after some fiddling around i could narrow it down to the iostream header, that's supposed to be preferred for I/O (SL.io.3).
#include <iostream>
int main() {
std::cout << "Hello World!\n";
return 0;
}
While gcc or clang's total output (main + a static initializer that calls some ios_base init functions) totals about 20 lines of assembly (after the Godbolt compiler explorer filters out directives and comments).
MSVC explodes it into 4000. Most of those lines are separate functions; MSVC's definition of main itself is 7 instructions vs. 8 for gcc/clang. (gcc/clang using GNU/Linux libstdc++ pass an extra length arg to the cout operator overload function, not just 2 pointers like MSVC does when using its own C++ library.)
If i use something like puts instead, MSVC's total output is reasonably compact and comparable to gcc/clang, like here.
Can someone kindly explain to me what is happening here, what im doing wrong or point me in the right direction?
Why are MSVC asm listings so bloated for simple functions using C++ libraries?
This may not be a complete answer, but I think I can explain much of the differences.
Much of the standard library (e.g., iostreams) is template heavy code. I believe the Microsoft compiler generates more template instantiations and relies on the linker to remove unnecessary ones. I think that's an effect of the different strategies the Windows linker uses versus most Posix ones, but it might also be a result of simply using a different standard library implementation.
If you specify /MD, which tells the compiler you intend to use the DLL version of the standard library, the generated code drops from 4000+ lines to fewer than 500 lines. I don't know precisely why that's the case. Perhaps MSVC knows the DLL library has all the necessary template instantiations while the static library depends on template instantiation from the compiler.
You can elicit an incremental improvement by handling only C++ exceptions (with /EHs). By default, the compiler will generate code that handles asynchronous system exceptions as well. And while your hello-world sample doesn't explicitly use exceptions, parts of the standard library probably do. At this point, it looks like a lot of the additional lines are setting up stack unwinding tables and calling destructors.
A lot of the remaining excess in the MSVC version looks like it exists to unwind the stack while calling destructors, so the exception handling model may be different.
I thought Compiler Explorer had a "clang-cl" option in the past but I don't see it now. clang-cl, generally speaking, is a command driver that interprets cl.exe options and adjusts default options to make clang produce code that's binary ABI compatible with Microsoft code. It would be interesting to see if it generates code like regular clang or whether it ends up emitting code more like MSVC.
I have been developing some hopefully generic C++ code using MS Visual Studio 2008 / Windows. The code is ultimately going to be used within both IOS and Android apps. After some initial testing we found that my program behaved differently on Android/IOS and we traced this down to different values of RAND_MAX. Now the code is behaving better, but it is still not exactly the same as on Windows and it is a tricky process finding the differences, especially as I do not have the IOS/Android development environments set up at my end and my client is in a different time zone.
My question is, what could I do to avoid issues with different subtle compiler differences. For example is there a way of making one compiler behave like another? Or perhaps a website that lists common problems with compiler differences?... any ideas?
EDIT: The program does not employ any third party libraries.
The way to make code easier to go from one compiler to another is to make your code as standard compliant as possible. If you take RAND_MAX as an example the C11 7.22.2.1 (5) standard says
The value of the RAND_MAX macro shall be at least 32767
So if you are using RAND_MAX you have to take into account that it could be more than 32767 depending on what compiler you are using.
I would suggest getting a copy of both the C and C++ standards and start getting familiar with them. Whenever you are going to make an assumption of how the code will be treated you should consult those standard to make sure that you are using well defined behavior.
If you are having problems with RAND_MAX being different, it does imply that you're also using srand and rand - are you using them? Keep in mind that no standard actually say what pseudo random number generator they need to implement, so you will not get the same sequence of random numbers on different platforms even if RAND_MAX happens to have the same value. In order to get identical sequences of random numbers on varying platforms, you need to implement a pseudo random number generator of your own - see e.g. http://en.wikipedia.org/wiki/Linear_congruential_generator for an example of a very simple one.
As for the rest of your question - in most cases, it's not compiler differences that will cause you problems (i.e., as long as you don't rely on undefined behaviour or odd corner cases, chances are that your code itself will behave the same assuming that it doesn't fail to compile at all), but differences in the APIs and environment. In this case, RAND_MAX doesn't depend on the compiler, but is a feature of the standard C library of your target platform.
So if your code fails to compile, you clearly are relying on some nonstandard feature of the language (or nonstandard/nonportable API), but if it does compile but behaves differently, you're relying on some undefined detail in the standard C/C++ libraries.
In my work, our code is compiled with Visual 2008 (and soon 2013), gcc 4.8 on Linux, gcc 4.8 for Android, XCode (clang) for iOS. We're doing standard C++, or try to, but each compiler has its own way to deal with what standard defines.
The best thing to do is use only standard librairies (STL, boost), as much as possible. If there are some functions that are available only on one platform or compiler, you have to define a generic one yourself, and call each one for each platform.
And for what I've seen, building with gcc, almost 90% of the code (if not 99%) will be good on Android and iOS.
You can give a try with cygwin and gcc, that runs on Windows, that could help you to detect issues before your code is tested on other platforms.
I know that some functions like sin cos min max memcpy may be treated not as normal functions but may be replaced by built-in functions (which may be more optimal than merely inline function calls, when the replacement is (an) actual processor instruction(s), such as directly calling the FSIN instruction for standard sin function when compiled for an x86 with a floating point unit).
The question I would like to use power of built-in functions (in C/C++ mostly in mingw/gcc maybe other compiler) but I do not want to link to libc, the Standard C Library).
Is it possible to use builtins with not linking to libc?
Are they any command line flags needed to optimize those symbols as a built-ins?
(Related to previous, but rephrased)
Will they be automatically recognized by name, or are compiler flag(s) necessary to enable usage of built-ins?
#randomusername has already explained the usage of the __builtin_ prefix for many common Standard C Library functions. I recommend using #define to make the change, while keeping your code clean.
#include <math.h>
#define cos __builtin_cos
#define sin __builtin_sin
#define printf __builtin_printf
...
printf("Distance is %f\n", cos(M_PI/4.0) * 7);
...
No Standard C Library
Now to not use the Standard C Library, which means not linking to it, or including the typical startup and exit code stubs, well, with GCC that is possible with the -nostdlib which is equivalent to -nostartfiles and -nodefaultlibs.
The issue is that you then have to replace all the library functions you would normally use, including system calls (or their wrappers / macros from glibc) for any kernel based functions.
I don't know of a portable or robust method that works across processors or even necessarily different families (sysenter vs. syscall (instruction) vs. int 0x80 for various 32 and 64-bit x86 processors). There is issues with ELF Auxiliary Vectors (Elf32_auxv_t) and vDSO (virtual ELF dynamic shared object) that may be possible to address and create a portable solution, I don't know.
Entry Point
I believe all GCC environments use the same default entry point, which is the label/function _start. This is normally included in the "Startup files" and then calls the traditional C/C++ entry point of main. So you would need to replace it with a minimal stub of your own (which can be in C).
Program termination
I don't know how to replace _exit(rc) or similar function required to correct terminate the program, in a portable fashion. For example in a Linux environment it needs to make a system call to the kernel function SYS_exit (aka __NR_exit or sys_exit)
void _start(void) {
int rc;
/* Get command line arguments if necessary */
rc = main(0, NULL);
your_exit_replacement(rc);
}
Alternatives
Normally user processes i.e. application programs, as opposed to Operating System kernels or drivers, accept the overhead of linking the Startup Files and the necessary overhead to enable dynamic linking to the Startard C Library, as memory is considered cheap and readily available that for any real (actually does something) application the memory saving is not worthwhile. In embedded domain, where it is not as acceptable to just assume plenty of memory is available, the alternative is the use a minimal libc replacement. For Linux there are several available (e.g. musl, uClibc, dietlibc), I don't know if there is one available for mingw or Windows-compatible open source replacements (ReactOS, and Wine).
Further
For further information, from a Linux platform point of view, there is a nice introduction "Hello from a libc-free world!" Part 1 and Part 2 by Jessica McKellar blogging at Oracle. There are also a number of related questions, and some (partial in some cases) answers here at stackoverflow about using -nostdlib in various circumstances.
Where to go from here depends on your goals: education, embedded, tiny program (Linux ELF executable) or Windows PE executable competitions.
Microsoft Windows
There are various articles for a Microsoft Windows environment dealing with .COM and .EXE executables, and Windows PE but using Microsoft's Visual Studio environment or assembly typically. The "classics" are Matt Pietrek's Under the Hood column "Reduce EXE and DLL Size with LIBCTINY.LIB" (January 2001 issue of MSDN Magazine) and "Remove Fatty Deposits from Your Applications Using Our 32-Bit Liposuction Tools" from October 1996 Microsoft Systems Journal. Another article, but I haven't read myself, that appears to have include explanations is "Reducing Executable Size".
Lets say you wanted to replace the function cos, all you have to do is replace every occurance of cos in your code with __builtin_cos. The same goes for any other function that you can replace with the compiler's version. Just prepend __builtin_ to the name.
For more information consult the gcc manual.
I have to import and work with a C++ Project. However, I canĀ“t get it to run without Microsoft Visual Studio. The Author of the project told me, I have to use a Microsoft Compiler, because only this one can handle particular notations he used (e.g. creating Objects on the fly while passing it to a method). See example.
lights.push_back(Light(Vector(dirx,diry,dirz).normalize(), Color(colr, colg, colb)));
I had to create an vector object before and pass it to the method.
Can anyone tell me which compiler I can use?
I dont have enough bit flow to download 3 gb Visual Studio.
Great but not necessary would be a compiler that I can use on Mac OS.
cheers.
Any C++ compiler can 'create objects on the fly while passing it to a function' (these are often known as temporary objects or rvalues).
What Visual C++ can do that other C++ compilers generally can't is pass those temporary objects to functions through parameters that are non-const references. The C++ standard specifically forbids that behavior, but MSVC allows it (Microsoft calls it an extension).
I'm guessing that that is the behavior the Author of the project is depending on.
If you are working on Mac OS, then the default compiler is (for recent version) Clang (based on LLVM).
And you are lucky in that Clang has a compatibility mode for parsing MSVC code that is normally quite advanced. The current top of the tree version is able to parse near every MFC generated header for example.
You can activate this mode using -fms-extensions.
A program written in Visual C/C++ 2005/2008 might not compile with another compiler such as GNU C/C++ or vice-versa. For example when trying to reuse code, which uses windows.h, written for a particular compiler with another, what are the differences to be aware of?
Is there any information about how to produce code which is compatible with either one compiler or another e.g. with either GC/C++ or MSVC/C++? What problems will attempting to do this cause?
What about other compilers, such as LCC and Digital Mars?
The first thing to do when trying to compile code written for MSVC to other compilers is to compile it with Microsoft-extensions switched off. (Use the /Za flag, I think). That will smoke out lots of things which GCC and other compilers will complain about.
The next step is to make sure that Windows-specific APIs (MFC, Win32, etc.) are isolated in Windows-specific files, effectively partioning your code into "generic" and "windows-specific" modules.
Remember the argument that if you want your web page to work on different browsers, then you should write standards-compliant HTML?
Same goes for compilers.
At the language level, if your code compiles without warnings on GCC with -std=c89 (or -std=c++98 for C++), -pedantic -Wall, plus -Wextra if you're feeling brave, and as long as you haven't used any of the more blatant GNU extensions permitted by -pedantic (which are hard to do accidentally) then it has a good chance of working on most C89 compilers. C++ is a bit less certain, as you're potentially relying on how complete the target compiler's support is for the standard.
Writing correct C89 is somewhat restrictive (no // comments, declarations must precede statements in a block, no inline keyword, no stdint.h and hence no 64bit types, etc), but it's not too bad once you get used to it. If all you care about is GCC and MSVC, you can switch on some language features you know MSVC has. Otherwise you can write little "language abstraction" headers of your own. For instance, one which defines "inline" as "inline" on GCC and MSVC/C++, but "__inline" for MSVC/C. Or a MSVC stdint.h is easy enough to find or write.
I've written portable code successfully in the past - I was working mostly on one platform for a particular product, using GCC. I also wrote code that was for use on all platforms, including Windows XP and Mobile. I never compiled it for those platforms prior to running a "test build" on the build server, and I very rarely had any problems. I think I might have written bad code that triggered the 64bit compatibility warning once or twice.
The Windows programmers going the other way caused the occasional problem, mostly because their compiler was less pedantic than ours, so we saw warnings they didn't, rather than things that GCC didn't support at all. But fixing the warnings meant that when the code was later used on systems with more primitive compilers, it still worked.
At the library level, it's much more difficult. If you #include and use Windows APIs via windows.h, then obviously it's not going to work on linux, and the same if you use KDE with GCC and then try to compile with MSVC.
Strictly speaking that's a platform issue, not a compiler issue, but it amounts to the same thing. If you want to write portable code, you need an OS abstraction API, like POSIX (or a subset thereof) that all your targets support, and you need to be thinking "portable" when you write it in the first place. Taking code which makes heavy use of windows-specific APIs, and trying to get it to work on GCC/linux, is basically a complete rewrite AFIAK. You might be better off with WINE than trying to re-compile it.
You're mixing up "compilers" and "OSs". <windows.h> is not something that MSVC C compiler brings to the table: it's C-specific embodiment of Windows API. You can get it independently from Visual Studio. Any other C compiler on Windows is likely to provide it. On the Linux side, for example, you have <unistd.h>, <pthereads.h> and others. They are not an essential part of GCC, and any other compiler that compiles for Linux would provide them.
So you need to answer two different questions: how can I code C in such a way that any compiler accepts it? And how do I hide my dependencies on OS?
As you can tell from the diverse answers, this topic is fairly involved. Bearing that in mind here are some of the issues I faced when recently porting some code to target three platforms (msvc 8/Windows, gcc 4.2/Linux, gcc 3.4/embedded ARM9 processor). It was originally only compiling under Visual Studio 2005.
a) Much code that's written on the Windows platforms uses types defined in windows.h. I've had to create a "windows_types.h" file with the following in it:
#ifndef _WIN32
typedef short INT16;
typedef unsigned short UINT16;
typedef int INT32;
typedef unsigned int UINT32;
typedef unsigned char UCHAR;
typedef unsigned long long UINT64;
typedef long long INT64;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef void * HANDLE;
typedef long LONG;
#endif
Ugly, but much easier than modifying the code that, previously, was only targeting Windows.
b) The typename keyword was not required in templated code to declare types. MSVC is lax in this regard (though I assume certain compiler switches would have generated a warning). Had to add it in a number of places.
c) Simple, but time-consuming: Windows is not case sensitive and many #included files were specified with incorrect case causing problems under Linux.
d) There was a fair chunk of code using the Windows API for many things. An example was for CRITICAL_SECTIONS and INTERLOCKED_INCREMENT. We used the boost libraries as much as possible to replace these issues but reworking code is time-consuming.
e) A lot of the code relied on headers being included in precompiled headers. We had issues with using pch on gcc3.4 so we had to ensure that all .h/cpp files correctly included all their dependencies (as they should have in the first place).
f) VS 2005 has two nasty bugs. auto_ptr's can be assigned to anything and temporary variables are allowed to be passed to reference parameters. Both fail to compile (thankfully!) under gcc but rework is required.
g) Bizarrely, we had template code that was trying to explicitly specialise class template functions. Not allowed. Again gcc refused, VS 2005 let it go. Easy enough to rework into regular overloads once the problem is understood.
h) Under VS 2005 std::exception is allowed to be constructed with a string. Not allowed under gcc or the standard. Rework your code to prefer to use one of the derived exception classes.
Hopefully that's the kind of information you were looking for!
Well this is a quite difficult question. Fact is that MSVC does not support the newest
C standard, about it's c++ compliance I can tell you anyything. Howerver "windows" C is understand by both MSVC and gcc you just can not hope for the other way. E.g if you use ANSI C99 features then you might have a hard time "porting" from gcc to MSVC.
But as long as you try the way MSVC-> gcc you chances will be better. The only point you have to be aware of is the libraries. Most of the libraries on Windows are supposed to work with MSVC and so you need some extra tools to make them accessible to gcc also.
LCC is a quite older system,which AFAIKT does not support much from ANSI C99, it also needs tools from MSVC to work properly. LCC is "just " a compiler.
lcc-win32 is a C Development system striving to be ANSI C99 compliant. It comes along with linker, IDE etc.
I can not tell about the state of Digital Mars implementation
Then there is also Pelles-C which is a fully fledged IDE also.
And we have hanging around OpenWatcom. Which once was quite a decent system but I can't tell how conformant it is.
All in all the "best" you can hope for the easier way from MSVC -> other system but it will probably be much worse the other way round.
Regards
Friedrich
vs2008 is a lot more standards compliant than 2005.
I have had more problems going the other way, especially the 'feature' of gcc that lets you allocate an array with a variable size at run time "int array[variable]" which is just pure evil.
A program written in Visual C/C++ 2005/2008 might not compile with another compiler such as GNU C/C++ or vice-versa.
This is true if you either (1) use some sort of extension available in one compiler but not another (the C++ standard, for instance requires the typename and template keywords in a few places but many compilers -- including Visual C++ don't enforce this; gcc used to not enforce this either, but changed in 3.4) or (2) use some standard compliant behavior implemented on one compiler but not another (right now the poster boy for this is exported templates, but only one or two compilers support this, and Visual C++ and gcc are not in that group).
For example when trying to reuse code, which uses windows.h, written for a particular compiler with another,
I've never seen a problem doing this. I have seen a problem using Microsoft's windows.h in gcc. But when I use gcc's windows.h in gcc and Microsoft's windows.h in Visual C++ I have access to all of the documented functions. That's the definitions of "implemented windows.h" after all.
what are the differences to be aware of?
The main one I've seen is people not knowing about the dependent template/typename thing mentioned above. I find it funny that a number of people think gcc is not smart enough to do what Visual C++ does, when in reality gcc had the feature first and then decided to remove it in the name of standards compliance.
In the near future you will run into problems using C++0x features. But both gcc and Visual C++ have implemented the easier things in that standard.