I have cpp and h of class file. Class implementation contains wcsncpy function that only might be used if defined _CRT_SECURE_NO_WARNINGS. It works if I place #define _CRT_SECURE_NO_WARNINGS before all header inclusions. But why I can't place this line after headers or event just before wcsncpy usage?
UPD
According to my understanding I can do #define in code:
int _tmain(int argc, _TCHAR* argv[])
{
#define a
#ifdef a
std::wcout << _T("hello") << std::endl;
#endif
}
Why definition below not works?
int main(void)
{
...
#define _CRT_SECURE_NO_WARNINGS
wcsncpy(dest, src, 4);
...
}
You can suppress a warning (even this one is treated as error by default) locally with pragma warning:
#pragma warning(push)
#pragma warning(disable: 4996) // 'wcsncpy': This function or variable may be unsafe.
wcsncpy(dest, src, 4);
#pragma warning(pop)
It is even possible to wrap this in more readable macros with Microsoft-specific __pragma keyword:
#define DISABLE_CRT_SECURE_WARNINGS() \
__pragma(warning(push)) \
__pragma(warning(disable: 4996))
#define RESTORE_CRT_SECURE_WARNINGS() \
__pragma(warning(pop))
...
DISABLE_CRT_SECURE_WARNINGS();
wcsncpy(dst, src, 4);
RESTORE_CRT_SECURE_WARNINGS();
Related
code:
// -*- C++ -*- forwarding header.
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** #file include/cwchar
* This is a Standard C++ Library file. You should #c \#include this file
* in your programs, rather than any of the #a *.h implementation files.
*
* This is the C++ version of the Standard C Library header #c wchar.h,
* and its contents are (mostly) the same as that header, but are all
* contained in the namespace #c std (except for names which are defined
* as macros in C).
*/
//
// ISO C++ 14882: 21.4
//
#pragma GCC system_header
#include <bits/c++config.h>
#if _GLIBCXX_HAVE_WCHAR_H
#include <wchar.h>
#endif
#ifndef _GLIBCXX_CWCHAR
#define _GLIBCXX_CWCHAR 1
// Need to do a bit of trickery here with mbstate_t as char_traits
// assumes it is in wchar.h, regardless of wchar_t specializations.
#ifndef _GLIBCXX_HAVE_MBSTATE_T
extern "C"
{
typedef struct
{
int __fill[6];
} mbstate_t;
}
#endif
namespace std
{
using ::mbstate_t;
} // namespace std
// Get rid of those macros defined in <wchar.h> in lieu of real functions.
#undef btowc
#undef fgetwc
#undef fgetws
#undef fputwc
#undef fputws
#undef fwide
#undef fwprintf
#undef fwscanf
#undef getwc
#undef getwchar
#undef mbrlen
#undef mbrtowc
#undef mbsinit
#undef mbsrtowcs
#undef putwc
#undef putwchar
#undef swprintf
#undef swscanf
#undef ungetwc
#undef vfwprintf
#if _GLIBCXX_HAVE_VFWSCANF
# undef vfwscanf
#endif
#undef vswprintf
#if _GLIBCXX_HAVE_VSWSCANF
# undef vswscanf
#endif
#undef vwprintf
#if _GLIBCXX_HAVE_VWSCANF
# undef vwscanf
#endif
#undef wcrtomb
#undef wcscat
#undef wcschr
#undef wcscmp
#undef wcscoll
#undef wcscpy
#undef wcscspn
#undef wcsftime
#undef wcslen
#undef wcsncat
#undef wcsncmp
#undef wcsncpy
#undef wcspbrk
#undef wcsrchr
#undef wcsrtombs
#undef wcsspn
#undef wcsstr
#undef wcstod
#if _GLIBCXX_HAVE_WCSTOF
# undef wcstof
#endif
#undef wcstok
#undef wcstol
#undef wcstoul
#undef wcsxfrm
#undef wctob
#undef wmemchr
#undef wmemcmp
#undef wmemcpy
#undef wmemmove
#undef wmemset
#undef wprintf
#undef wscanf
#if _GLIBCXX_USE_WCHAR_T
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
using ::wint_t;
using ::vfwscanf;
using ::btowc;
using ::fgetwc;
using ::fgetws;
using ::fputwc;
using ::fputws;
using ::fwide;
using ::fwprintf;
using ::fwscanf;
using ::getwc;
using ::getwchar;
using ::mbrlen;
using ::mbrtowc;
using ::mbsinit;
using ::mbsrtowcs;
using ::putwc;
using ::putwchar;
#ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF
using ::swprintf;
#endif
using ::swscanf;
using ::ungetwc;
using ::vfwprintf;
#ifndef _GLIBCXX_HAVE_WFWSCANF;
if _GLIBCXX_HAVE_VFWSCANF
using ::vfwscanf;
#endif
#ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF
using ::vswprintf;
#endif
#if _GLIBCXX_HAVE_VSWSCANF
using ::vswscanf;
#endif
using ::vwprintf;
#if _GLIBCXX_HAVE_VWSCANF
using ::vwscanf;
#endif
using ::wcrtomb;
using ::wcscat;
using ::wcscmp;
using ::wcscoll;
using ::wcscpy;
using ::wcscspn;
using ::wcsftime;
using ::wcslen;
using ::wcsncat;
using ::wcsncmp;
using ::wcsncpy;
using ::wcsrtombs;
using ::wcsspn;
using ::wcstod;
#if _GLIBCXX_HAVE_WCSTOF
using ::wcstof;
#endif
using ::wcstok;
using ::wcstol;
using ::wcstoul;
using ::wcsxfrm;
using ::wctob;
using ::wmemcmp;
using ::wmemcpy;
using ::wmemmove;
using ::wmemset;
using ::wprintf;
using ::wscanf;
using ::wcschr;
using ::wcspbrk;
using ::wcsrchr;
using ::wcsstr;
using ::wmemchr;
#ifndef __CORRECT_ISO_CPP_WCHAR_H_PROTO
inline wchar_t*
wcschr(wchar_t* __p, wchar_t __c)
{ return wcschr(const_cast<const wchar_t*>(__p), __c); }
inline wchar_t*
wcspbrk(wchar_t* __s1, const wchar_t* __s2)
{ return wcspbrk(const_cast<const wchar_t*>(__s1), __s2); }
inline wchar_t*
wcsrchr(wchar_t* __p, wchar_t __c)
{ return wcsrchr(const_cast<const wchar_t*>(__p), __c); }
inline wchar_t*
wcsstr(wchar_t* __s1, const wchar_t* __s2)
{ return wcsstr(const_cast<const wchar_t*>(__s1), __s2); }
inline wchar_t*
wmemchr(wchar_t* __p, wchar_t __c, size_t __n)
{ return wmemchr(const_cast<const wchar_t*>(__p), __c, __n); }
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#if _GLIBCXX_USE_C99_WCHAR
#undef wcstold
#undef wcstoll
#undef wcstoull
namespace __gnu_cxx
{
#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC
extern "C" long double
(wcstold)(const wchar_t * __restrict, wchar_t ** __restrict) throw ();
#endif
#if !_GLIBCXX_USE_C99_DYNAMIC
using ::wcstold;
#endif
#if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
extern "C" long long int
(wcstoll)(const wchar_t * __restrict, wchar_t ** __restrict, int) throw ();
extern "C" unsigned long long int
(wcstoull)(const wchar_t * __restrict, wchar_t ** __restrict, int) throw ();
#endif
#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
using ::wcstoll;
using ::wcstoull;
#endif
} // namespace __gnu_cxx
namespace std
{
using ::__gnu_cxx::wcstold;
using ::__gnu_cxx::wcstoll;
using ::__gnu_cxx::wcstoull;
} // namespace
#endif
#endif //_GLIBCXX_USE_WCHAR_T
#if __cplusplus >= 201103L
#ifdef _GLIBCXX_USE_WCHAR_T
namespace std
{
#if _GLIBCXX_HAVE_WCSTOF
using std::wcstof;
#endif
#if _GLIBCXX_HAVE_VFWSCANF
using std::vfwscanf;
#endif
#if _GLIBCXX_HAVE_VSWSCANF
using std::vswscanf;
#endif
#if _GLIBCXX_HAVE_VWSCANF
using std::vwscanf;
#endif
#if _GLIBCXX_USE_C99_WCHAR
using std::wcstold;
using std::wcstoll;
using std::wcstoull;
#endif
} // namespace
#endif // _GLIBCXX_USE_WCHAR_T
#endif // C++11
error:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\cwchar|164|error: expected unqualified-id before 'if'|
This is just trying to build and run the "hello world" start-up page, do not know what to do, fixed some mistakes with debugger, but this is just a pain and out of my depth of knowledge, never had this before
Line 164 is the one indicated here:
#ifndef _GLIBCXX_HAVE_WFWSCANF;
if _GLIBCXX_HAVE_VFWSCANF // this one
using ::vfwscanf;
#endif
It seems you have accidentally removed the # in front of the if there.
You should mark the entire tree read-only using file permissions to avoid this.
For some odd reason, two erroneous lines have made their way to your compiler's cwchar file.
#ifndef _GLIBCXX_HAVE_WFWSCANF; // This looks erroneous
if _GLIBCXX_HAVE_VFWSCANF // Should be preprocessor if (#if)
using ::vfwscanf;
#endif
I downloaded and checked the gcc-c++-6.3.0-1-mingw32 cwchar file, and surely it does not include that erroneous line:
#if _GLIBCXX_HAVE_VFWSCANF
using ::vfwscanf;
#endif
There wasn't enough #endifs for the #ifndef _GLIBCXX_HAVE_WFWSCANF; to be valid. Also, your copy pasted code seems to be missing an #endif from the very end:
#endif // _GLIBCXX_USE_WCHAR_T
#endif // C++11
#endif
For why the the error was generated, if the _GLIBCXX_HAVE_VFWSCANF was defined, the non-preprocessor if statement would expand like this:
if 1
using ::vfwscanf;
#endif
Maybe while looking at the compiler errors with your IDE you accidentally did some backspacing, cutting or copy pasting, or maybe your installation of mingw is somehow faulty? Hard to guess.
Either way, I would just remove the erroneous line and add the #endif to the end, if it was missing. If more errors show up in the compiler's files, I would consider reinstalling mingw.
In MSVC & C#, #pragma region can be used to label a code section.
Similarly, in GCC/Clang, #pragma mark can accomplish the same thing.
Is it possible to define a single macro such as CODELABEL(label) which will work for both compilers?
Basically, I'd like to avoid having to do the following:
#ifdef _WIN32
#pragma region Variables
#else
#pragma mark Variables
#endif
bool MyBool;
int MyInt;
#ifdef _WIN32
#pragma region Methods
#else
#pragma mark Methods
#endif
void MyMethod();
void AnotherMethod();
... and instead, do something like this:
CODELABEL( Variables )
bool MyBool;
int MyInt;
CODELABEL( Functions )
void MyMethod();
void AnotherMethod();
Is something like this possible?
Yes, in C++11, you can use _Pragma, since using #pragma in a macro definition is not allowed:
#ifdef _WIN32
#define PRAGMA(x) __pragma(x) //it seems like _Pragma isn't supported in MSVC
#else
#define PRAGMA(x) _Pragma(#x)
#endif
#ifdef _WIN32
#define CODELABEL(label) PRAGMA(region label)
#else
#define CODELABEL(label) PRAGMA(mark label)
#endif
The dance with PRAGMA is to satisfy _Pragma requiring a string literal, where side-by-side concatenation of two string literals (e.g., "mark" "section label") doesn't work.
According to this topic, the following should work.
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
#ifdef _WIN32
#define LABEL region
#else
#define LABEL mark
#endif
and then
#pragma STR(LABEL) Variables
bool MyBool;
int MyInt;
#pragma STR(LABEL) Functions
void MyMethod();
void AnotherMethod();
As far as Windows and macOS are concerned, since Xcode 12 and Visual Studio 2019, you can easily use this syntax that works ok on both platforms:
#pragma region mark -
#pragma region mark Whathever Your Label
Xcode silently ignores the 'region' token while VS takes the 'mark' token as part of the label, which is a minor cosmetic issue, IMHO.
Is it possible to disable chunks of code with c/c++ preprocessor depending on some definition, without instrumenting code with #ifdef #endif?
// if ENABLE_TEST_SONAR is not defined, test code will be eliminated by preprocessor
TEST_BEGIN(SONAR)
uint8_t sonar_range = get_sonar_measurement(i);
TEST_ASSERT(sonar_range < 300)
TEST_ASSERT(sonar_range > 100)
TEST_END
Functionally equivalent to something as follows:
#ifdef TEST_SONAR
serial_print("test_case sonar:\r\n");
uint8_t sonar_range = get_sonar_measurement(i);
serial_print(" test sonar_range < 300:%d\r\n", sonar_range < 300);
serial_print(" test sonar_range > 100:%d\r\n", sonar_range > 100);
#endif TEST_SONAR
Multiple lines can be disabled only with #ifdef or #if but single lines can be disabled with a macro. Note that multiple lines can be combined with \
#ifdef DOIT
#define MYMACRO(x) \
some code \
more code \
even more \
#else
#define MYMACRO(x)
#endif
Then when you call MYMACRO anplace that code will either be included or not based on whether DOIT is defined
That's the closest you can come and is used frequently for debugging code
EDIT: On a whim I tried the following and it seems to work (in MSVC++ and g++):
#define DOIT
#ifdef DOIT
#define MYMACRO(x) x
#else
#define MYMACRO(x)
#endif
void foo(int, int, int)
{
}
int main(int, char **)
{
int x = 7;
MYMACRO(
if (x)
return 27;
for (int i = 0; i < 10; ++i)
foo(1, 2, 3);
)
}
No, the only way to disable sections of codes effectively using preprocessing is by #ifdef #endif. Theoretically, you could use #if identifier, but it's better to stick to checking whether a variable is defined.
Another option (perhaps) is to use a preprocessing macro:
Edit:
Perhaps using plain functions and #ifdef might work better?
function test_function() {
/* Do whatever test */
}
#define TESTING_IDENTIFIER
#define TEST( i, f ) if ((i)) do { f } while (0)
Then, for each test, you define a unique identifier and call it by providing the identifier first and the function (with parenthesis) second.
TEST( TESTING_IDENTIFIER, test_function() );
Finally, f can be anything that's syntactically correct -- You don't have to create a function for every test, you can put the code inline.
I will anyway mention an obvious solution of
#define DO_TEST_SONAR
#ifdef DO_TEST_SONAR
#define TEST_SONAR if(true) {
#else
#define TEST_SONAR if(false) {
#endif
#define TEST_SONAR_END }
...
TEST_SONAR
code
TEST_SONAR_END
The code will still get compiled, not completely removed, but some smart compilers might optimize it out.
UPD: just tested and
#include <iostream>
using namespace std;
//#define DO_TEST_SONAR
#ifdef DO_TEST_SONAR
#define TEST_SONAR if(true) {
#else
#define TEST_SONAR if(false) {
#endif
#define TEST_SONAR_END }
int main() {
TEST_SONAR
cout << "abc" << endl;
TEST_SONAR_END
}
produces absolutely identical binaries with cout line commented out and non commented, so indeed the code is stripped. Using g++ 4.9.2 with -O2.
I have a problem where I can't seem to get conditional #define preprocessors to work correctly. For example:
#define WIN32_BUILD
#ifdef WIN32_BUILD
#define PCH "stdafx.h"
#else
#define PCH "xyz.h"
#endif
#include PCH
If I use this form, the compiler tells me that it can't find 'stdafx.h'. OK, that seems odd, so if I change the code to....
#define WIN32_BUILD
#ifdef WIN32_BUILD
#define PCH "xyz.h"
#else
#define PCH "stdafx.h"
#endif
#include PCH
Then the file defined in PCH gets picked up and everything compiles fine. This seems odd to me, almost like the preprocessor is ignoring the #if directives and just using all the #defines that it encounters.
Obviously I am doing something wrong, and I was hoping that someone could help me understand this.
When a project has the precompiled header feature turned on the preprocessor ignores everything that comes before #include "stdafx.h"
So your #define statements are ignored.
TL:DR; #define defines the symbol, #ifdef tests if the symbol is defined not whether it has a value.
#define WIN32_BUILD
This defines a pre-processor token, WIN32_BUILD. The token has no value. Anywhere you use the token 'WIN32_BUILD' the pre-processor will substitute the empty string, i.e. nothing.
#ifdef WIN32_BUILD
This checks if the pre-processor token WIN32_BUILD is defined. It is, you just defined it.
#ifdef WIN32_BUILD
// true - this code is included.
#define PCH "stdafx.h"
This defines the pre-processor token, PCH, and assigns it the value "stdafx.h"
#else
#define PCH "xyz.h"
#endif
This code is ignored, because WIN32_BUILD was defined.
It looks as though you were expecting 'ifdef' to only evaluate to true if the expression was not defined /to/ something.
#define a
#define b SOMETHING
#ifdef a
// you are expecting this to be ignored
#endif
#ifdef b
// and expecting this not to be ignored
#endif
#ifdef and #if defined(...) do the same thing.
#define a
#define b SOMETHING
#if defined(a) && defined(b)
// this code will be evaluated, both tokens are defined.
#endif
This feature of pre-processor tokens is often used to support conditional functionality:
#if HAVE_CPP11_OVERRIDE_KEYWORD
#define OVERRIDE_FN override
#else
#define OVERRIDE_FN
#endif
struct A {
virtual void foo() {}
};
struct B : public A {
void foo() OVERRIDE_FN {}
};
In the above code, the override keyword is only added if the system supports it (determined outside of the code).
So a compiler with override sees
struct B : public A {
void foo() override {}
};
a compiler without it sees
struct B : public A {
void foo() {}
};
Note: The opposite of "ifdef" is "ifndef":
#define a
#define b SOMETHING
#undef c
//#define d // << we didn't define it.
int main() {
#ifdef a
#pramga message("a is defined")
#else
#pramga message("a is UNdefined")
#endif
#ifdef b
#pragma message("b is defined")
#else
#pramga message("b is UNdefined")
#endif
#ifdef c
#pramga message("c is defined")
#endif
#else
#pramga message("c is UNdefined")
#endif
#ifdef d
#pramga message("d is defined")
#endif
#else
#pramga message("d is UNdefined")
#endif
#ifndef d
#pragma message("d is not defined")
#endif
#ifndef a
#pragma message("a is not defined")
#endif
return 0;
}
You can assign a pre-processor token numeric values and test them with #if
#if _MSC_VER
#define WIN32_BUILD 1
#else
#define WIN32_BUILD 0
#endif
#if WIN32_BUILD
#include <Windows.h>
#endif
But, especially when doing cross-platform programming, people tend to use ifdef variants rather than numeric checks, because the value checks require you to explicitly ensure all of the tokens are defined with a value. It's a lot easier just to only define them when you need them.
I would like to display some log messages when debugging. One option is to use the very ugly
#ifdef DEBUG
std::cout << "I'm in debug mode!\n";
#endif
In the JUCE library, there is a nice macro that outputs text to the debugging pane
DBG("I'm in debug mode!")
The juce solution also allows you to do neat stuff like the following that would be desirable
int x = 4;
DBG(String("x=") + String(x))
I would like to know if a similarly neat method exists in std:: or boost::
Why not just write your own:
#ifdef DEBUG
#define DBG(x) std::cout << x;
#else
#define DBG(x)
#endif
For namespaces
namespace DBG
{
inline void DBG(const char* x)
{
#ifdef DEBUG
std::cout << x;
#endif
}
}
If you want something like printf, you should use a bit another macros:
void DebugPrintLn(const char* format, ...);
inline void Nothing(...) {}
#ifdef DEBUG
#define DBG DebugPrintLn
#else
#define DBG Nothing // Or __noop on Visual C++
#endif
Using Nothing is portable, but arguments still computed (__noop guarantees that any of argument will be not computed, VC++ specific). Better if you can use macros variable arguments (both available on GCC and latest VC++): you may even skip any argument computation in portable way:
#ifdef DEBUG
#define DBG(...) DebugPrintLn(__VAR_ARGS__)
#else
#define DBG(...) ((void)0)
#endif
In any case, you use it the same way:
DBG("Lucky day: %s %i", "Friday", 13);
I have also written my own portable TRACE macro. I share it here:
#ifdef ENABLE_TRACE
# ifdef _MSC_VER
# include <windows.h>
# include <sstream>
# define TRACE(x) \
do { std::stringstream s; s << (x); \
OutputDebugString(s.str().c_str()); \
} while(0)
# else
# include <iostream>
# define TRACE(x) std::clog << (x)
# endif // or std::cerr << (x) << std::flush
#else
# define TRACE(x)
#endif
example:
#define ENABLE_TRACE //can depend on _DEBUG or NDEBUG macros
#include "my_above_trace_header.h"
int main (void)
{
int v1 = 123;
double v2 = 456.789;
TRACE ("main() v1="<< v1 <<" v2="<< v2 <<'\n');
}
Any improvements/suggestions/contributions are welcome ;-)