$include in a C++ file, and other $ values in the code - c++

I have recently been given a sizeable chunk of legacy C++ code which I want to move to the latest VS2012 compiler or the GCC compiler.
When I look at some of the files however, I can see some items of code prefixed with a $ sign.
For example I have some include lines:
#include "utlString.h"
$include "gclFloat_c.h"
and an enum declaration:
$enum gclEFormatType
{
StandardFormat = 0, // e.g. 192784.272674700000000000
ScientificFormat = 1, // e.g. 1.927842726747E5 (includes exponent)
ExtendedFormat = 2 // e.g. 1.927842726747E5S30 (includes exponent and significant digit count)
};
and I have some other declarations:
$cointerface [dual] gclIFloat : IDispatch
{
...
}
$coclass [STA] gclCFloat;
I think they may be pre-processor macros, but I'm not sure. Can anyone tell me what there are and how are they used?
Thanks

There are three possibilities:
The code is run through some external preprocessor before being fed to the compiler;
It's some compiler-specific extension (check your compiler's documentation); or
It's a syntax error.

Looks like those files are intended to be parsed to generate include files for both c++ and a scripting wrapper, like swig, but the [dual] and [sta] make me think it's targeting C# as the second language.

It's likely to be Visual Studio nmake syntax.
You can find many tutorial about this on the internet, the dollar sign is also used as an identifier for tokens with a Visual Studio specific syntax ( outside nmake ).

Related

Visual Studio Code: exclude sections of a file from autoformat?

I'm dealing with a bunch of legacy C code whose formatting is all over the place and I would like to clean it up as I work. However, there are some sections that I do not want touched (or I'd rather format manually (such as structures being used as bitfields with an explanation as to what each bit represents in comments). I'm working in an embedded environment, so understanding what each bit represents is important and keeping that nicely formatted is important, however, the C-lang formatter in VS Code wants to do its own thing with this kind of stuff.
How can I exclude sections of a file from autoformat?
Are you using the clang-format extension clang-format ? If so, see disable formatting on a piece of code.
int formatted_code;
// clang-format off
void unformatted_code ;
// clang-format on
void formatted_code_again;

Can I do conditional selection of USE statements using preprocessor directives which rely on data from a file interface/header file in Fortran?

I would like to use different libraries in my fortran code (I am using intel fortran compiler as well) depending on which version of MKL is available at compile time. There is a file interface included with an install of MKL which defines preprocessor macros for version numbers and build date - /opt/intel/mkl/include/mkl.fi
I thought the flow would be as follows:
Get version number of MKL from file interface mentioned above
Use the version number to decide which library to use via preprocessor directives
execute use statement to compile with correct library
If I place any use statements after an include statement, however, the compilation aborts after throwing error #6278: This USE statement is not positioned correctly within the scoping unit.
Is there any way to achieve conditional selection of use statements using preprocessor directives which rely on information from a file interface or header file?
I cannot see how it is possible, because any use statements have to be before the include statement which provides the data required to decide which use statement to execute. I have included below a sample which demonstrates what I'm trying to do, but will not work·
module MKLVersion
!Test for definition and value up here
#ifdef INTEL_MKL_VERSION
#if INTEL_MKL_VERSION >= 110200
use LAPACK95, only : ggevx, geevx, sygvd
#elif INTEL_MKL_VERSION < 110200
use MKL95_LAPACK, only : ggevx, geevx, sygvd
#endif
#endif
! but dont actually get the definition till we get here
include '/opt/intel/mkl/include/mkl.fi'
end module MKLVersion
The short answer to this question is, ultimately, no - as Steve Lionel pointed out, the included file had INTERFACE statements, which cannot come before a USE statement.
However, I found a solution for my particular use case, which enables compilation of code with both old and new MKL versions. According to this intel article from 2009, there is a way to call libraries which will work with older version of MKL:
Notes:
* f95_precision.mod, mkl95_lapack.mod and mkl95_precision.mod files will be removed in one of the future releases. The current version supports two USE statements - so you can choose or "USE MKL95_LAPACK" or " USE LAPACK95 ". For the future compatibility we recommend using "USE LAPACK95" statement.
So USE MKL95_LAPACK can be replaced with USE LAPACK95 without breaking everything, which is good.

Prevent or generate warning for custom deprecations

I'm using C++11's static_assert to perform compile-time checks to prevent the use of insecure functions, and/or to provide feedback to the user when a new feature should be used and the relevant APIs are out of date (e.g. using std::strftime, std::to_string, etc.).
I want to force failure if any source code attempts to use outdated functions, but I need it to be totally cross-platform, and also bypass or workaround other 'helpers' such as Microsofts own deprecations.
I see I can use .sections when working with a gnu toolchain, which I can see the definition for in OpenBSD's cdefs.h (http://ninjalj.blogspot.co.uk/2011/11/your-own-linker-warnings-using-gnu.html) but I have nothing equivalent for Visual Studio.
For example, I can use the following code without a problem to prevent strcpy/strcat:
# define COMPILE_TIME_CHECK(expression, message) static_assert(expression, message)
# define GUARANTEE_FAILURE (0 == 1)
# define DISABLED_FUNCTIONS_MESSAGE_CSTRING "strcpy, strcat must be replaced with strlcpy and strlcat, respectively"
# define strcat COMPILE_TIME_CHECK(GUARANTEE_FAILURE, DISABLED_FUNCTIONS_MESSAGE_CSTRING);
it may be unclean but works; but the trouble is when attempting to do the same with others that don't play as nicely, such as ctime and localtime:
_CRT_INSECURE_DEPRECATE(localtime_s) static __inline struct tm * __CRTDECL localtime(const time_t * _Time)
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\time.inl(86): error C2059: syntax error : 'static_assert'
Is there a way I can block specific functions (warning or compile failure), while providing a message for what to use in their place, without conflict from gcc/visual studio in a suitable way? The CRT macros in visual studio do not prevent the above error with the aforementioned defines.
I'm not convinced something like __declspec(deprecated) int strcpy(char*,char*); (as noted here: C++ mark as deprecated) is going to always play ball, and is a lot more work & less descriptive than just setting a define for the function name.
you can use Disable:warning {#warning Code}

C/C++ preprocessor directive for handing compilation errors

The title might be somewhat confusing, so I'll try to explain.
Is there a preprocessor directive that I can encapsulate a piece of code with, so that if this piece of code contains a compilation error, then some other piece of should be compiled instead?
Here is an example to illustrate my motivation:
#compile_if_ok
int a = 5;
a += 6;
int b = 7;
b += 8;
#else
int a = 5;
int b = 7;
a += 6;
b += 8;
#endif
The above example is not the problem I am dealing with, so please do not suggest specific solutions.
UPDATE:
Thank you for all the negative comments down there.
Here is the exact problem, perhaps someone with a little less negative approach will have an answer:
I'm trying to decide during compile-time whether some variable a is an array or a pointer.
I've figured I can use the fact that, unlike pointers, an array doesn't have an L-value.
So in essence, the following code would yield a compilation error for an array but not for a pointer:
int a[10];
a = (int*)5;
Can I somehow "leverage" this compilation error in order to determine that a is an array and not a pointer, without stopping the compilation process?
Thanks
No.
It's not uncommon for large C++ (and other-language) projects to have a "configuration" stage designed into their build system to attempt compilation of different snippets of code, generating a set of preprocessor definitions indicating which ones worked, so that the compilation of the project proper can then use the preprocessor definitions in #ifdef/#else/#endif statements to select between alternatives. For many UNIX/Linux software packages, running the "./configure" script coordinates this. You can read about the autoconf tool that helps create such scripts at http://www.gnu.org/software/autoconf/
This is not supported in standard C. However, many command shells make this fairly simple. For example, in bash, you can write a script such as:
#!/bin/bash
# Try to compile the program with Code0 defined.
if cc -o program -DCode0= "$*"; then
# That worked, do nothing extra. (Need some command here due to bash syntax.)
/bin/true
else
# The first compilation failed, try without Code0 defined.
cc -o program "$*"
fi
./program
Then your source code can test whether Code0 is defined:
#if defined Code0
foo bar;
#else
#include <stdio.h>
int main(void)
{
printf("Hello, world.\n");
return 0;
}
#endif
However, there are usually better ways to, in effect, make source code responsive to the environment or the target platform.
On the updated question :
If you're writing C++, use templates...
Specifically, to test the type of a variable you have helpers : std::enable_if, std::is_same, std::is_pointer, etc
See the type support module : http://en.cppreference.com/w/cpp/types
C11 _Generic macros might be able to handle this. If not, though, you're screwed in C.
Not in the C++ preprocessor. In C++ you can easily use overload resolution or a template or even expression SFINAE or anything like that to execute a different function depending on if a is an array or not. That is still occurring after preprocessing though.
If you need one that is both valid C and valid C++, the best you can do is #ifdef __cplusplus and handle it that way. Their common subset (which is mostly C89) definitely does not have something that can handle this at any stage of compilation.

C++ can't find non-standard C functions in global namespace

We have a fairly large C++ project which I am now in the process of moving to VS2010 and also updating a few libs along the way. So far everything builds just fine now, except I get (to me) quite weird errors where apparently a number of (edit: non-)standard C functions and symbols are not defined:
error C2039: 'strdup' : is not a member of '`global namespace'' ...\ACE_wrappers\ace\OS_NS_string.inl 222
...
error C2065: 'O_WRONLY' : undeclared identifier ...\ACE_wrappers\ace\OS_NS_unistd.inl 1057
...
This affects the following functions and symbols for me:
strdup getcwd O_WRONLY
putenv swab O_TRUNC
access unlink S_IFDIR
chdir mkdir S_IFREG
rmdir tempnam O_RDONLY
isascii
One part in the include file from ACE I experimented with was the strdup part which looks like this:
ACE_INLINE char *
ACE_OS::strdup (const char *s)
{
# if (defined (ACE_LACKS_STRDUP) && !defined(ACE_STRDUP_EQUIVALENT)) \
|| defined (ACE_HAS_STRDUP_EMULATION)
return ACE_OS::strdup_emulation (s);
# elif defined (ACE_STRDUP_EQUIVALENT)
return ACE_STRDUP_EQUIVALENT (s);
# elif defined (ACE_HAS_NONCONST_STRDUP)
return ::strdup (const_cast<char *> (s));
#else
return ::strdup (s);
# endif /* (ACE_LACKS_STRDUP && !ACE_STRDUP_EQUIVALENT) || ... */
}
There are loads of similar sections for other functions above and below, all of which compile just fine.
The path taken in my case is the last one, i.e. return ::strdup (s);. If I hit F12 on the ::strdup VS takes me to the declaration in string.h of the C standard library.
If I remove the namespace qualifier it builds, although IntelliSense tells me that it's now a recursive call so it probably won't work. If I change the namespace to std:: I get around 270 more errors, this time from several other projects. If I change the function to ::_strdup it builds. Including string.h as the very frst thing changes nothing.
(Nota bene: “it builds” refers to “this particular compiler error disappears at that location, but it still leaves the errors about the other functions, obviously.)
I'm a little at a loss here. I noticed that many larger libraries either build their own abstraction over the standard library or provide things that are not there by default and that was a point where ACE and ImageMagick already clashed (in both typedefing ssize_t but with incompatible definitions). Since we pull in quite a few libraries (I don't have an exact overview either, right now) this could well be another clash, caused by the wrong include order and similar things. This is also hinted at by the fact that the same includes from ACE apparantly work fine in other projects in the same solution.
Anyone have an idea what I could look for here at least? The build log with /showIncludes is just 24k lines so I don't exactly see many patterns there, except that string.h gets included way before the problematic ACE header.
And I wouldn't want to modify the library source code as that will only bite us again if we update to a newer version.
"a number of standard C functions and symbols are not defined"
strdup is not a standard C function. It is defined in POSIX, but not in C or C++. Quoting MSDN:
These POSIX functions are deprecated beginning in Visual C++ 2005. Use the ISO C++ conformant _strdup, _wcsdup, _mbsdup instead.
It appears to me that none of the symbols you list are standard C functions.
With Mark B's comment which prompted me to look at 12 MiB of Preprocessor output I was able to solve it. In string.h the snippet where strdup is defined looks like this:
#if !__STDC__
...
_Check_return_ _CRT_NONSTDC_DEPRECATE(_strdup) _CRTIMP char * __cdecl strdup(_In_opt_z_ const char * _Src);
It so happened that this single project defines the __STDC__ symbol which causes a lot of non-standard-C-but-still-in-the-C-standard-library (thanks, Robφ for nitpicking but not solving the issue) functions to disappear completely.
I know they're deprecated, I got plenty of warnings that tell me so. But as noted, I'm not maintaining project-specific patches to 3rd-party libraries we use just to have the same fun all over again if we ever update them.
If I understand VS correctly, the strdup, etc. function names are deprecated nowadays (not POSIX compliant, I think). You should use the underlined versions.
When this happened for me, I ran a global search and replace, since it seemed like a sensible thing to do and keeps the source code in good condition for the future (VS 2012 is already out! :) ).