Make/trick Visual C++ into indenting macros structure properly - c++

Consider these macros
#define BEGIN(Parent) void Process(){
#define ELEMENT(Elem) RegisterElement(Elem);
#define END }
When using them, Visual Studio will not recognize ELEMENT as part of a child code block and thus not indent it properly
BEGIN(ParentClass) <--- hit ENTER here and carret will go below `B` in begin, with no indentation
ELEMENT(m_member)
END
Is there a way to trick Visual Studio, as in a way I could code my macros or maybe some helpful pragmas so that Visual Studio recognizes the opening and closing scope of RegisterElement function and thus indend ELEMENT entries properly? Thanks

Use Code alignment extension for VS 2013/12/10
Here's url: https://visualstudiogallery.msdn.microsoft.com/7179e851-a263-44b7-a177-1d31e33c84fd
From Edit->Code Alignment menu, select 'Align from caret'

Related

Can visual studio or Visual Assist be set to automatically complete parentheses for macros?

For stl functions, such as accumulate, when I enter accu, and then press tab in the pop-up candidate list, the left bracket will be automatically generated and the cursor will be placed in the middle of the bracket, as shown in Figure 1
I know visual studio or Visual Assist can do this automatically
my question is,Is there a setting to perform such completion for macro commands as well?
For example, for the following macro, when I press D, D() can be automatically completed, and the cursor is placed in the middle of the brackets
#define D(x) cout << #x << " : " << x << endl;
Enable member list commit aggressive in Tools->Options ->Text editor-> C++ ->Advanced, then you can use shift+9 ( instead of tab to complete parentheses and place the cursor in the middle. Not all functions, macros need to add parentheses automatically. In addition, You can request a new feature to Developer Community and post the link here.

Why can't Intellisense find variables from a header file when including it into a namespace?

First of all thank you for taking the time to read and maybe answer this.
I want to include a compressed font, which has been converted from a .ttf file into a .h file.
The compressed font is saved (in the .h file) inside an array of the type:
static const unsigned int font_name_compressed_data[about 3 - 10 thousand]
For what I am using (ImGui) this is all fine and I can import the font correctly.
The problem is, when i want to encapsulate those font_name_compressed_data arrays (one for each font) within an namespace, intellisense suddenly stops recognizing them.
It still compiles fine, but intellisense does not work and it constantly shows that there are still errors.
I am using c++17 although i don't think that matters.
And I am compiling with Visual Studio 2019, while editing with Visual Studio Code.
Did I do it wrong the first time or is this a bug from intellisense?
~~ E D I T :
My assumption was wrong, after manually opening every font_name.hpp file and individually adding the namespace to it, intellisense was working again. But after closing and reopening it, the same error came back. It is either this
namespace "Fonts" has no member "roboto_compressed_data"
or this
name followed by '::' must be a class or namespace name
seemingly random.
If I autocomplete Fonts:: in Visual Studio 2019 I get all my fonts, but if I do the same thing in Visual Studio Code I dont get any, unless I manually open the font header file in Visual Studio Code and close it again.
Also the error comes back after doing Rescan Workspace.
I think I have my project set up right, since I don't get an error anywhere else when using namespaces or includes.
Seems like VS Code just unloads the font header file from memory or something, since it is pretty long, but I don't know...
When i do it like this it does not get recognized:
in the compressed_font.h
static const unsigned int font_name_compressed_data[size of the array] =
{ 0x0000bc57, 0x00000000, 0x78b30000, ... and so on }
where i then want to use it (.cpp):
namespace font_data
{
#include "compressed_font.h"
}
// ...
// v--- This is then unrecognized
font_data::font_name_compressed_data
But after i changed everything to this it got recognized again:
in the compressed_font.h
namespace font_data
{
static const unsigned int font_name_compressed_data[size of the array] =
{ 0x0000bc57, 0x00000000, 0x78b30000, ... and so on }
}
where i then want to use it (.cpp):
#include "compressed_font.h"
// ...
// v--- This is now recognized
font_data::font_name_compressed_data

Add line to comment in Visual Studio C++

I'm looking for something rather specific.
Let's say I define something like a variable, and add a comment to it.
#define ARDUINO_READ_Q0 //Read pins 22-29
Now, any time I start typing ARDUINO_READ_Q0, it pops up in Visual Studio's list of available values, and when you hover over it, it comes up with a tooltip saying "Read pins 22-29"
Is there any way to add a line to this tooltip? I thought of something like this:
#define ARDUINO_READ_Q0 /* Read pins 22-29
Return 1B */
However, I would prefer for it to remain on a single line when I define it.
To give you an idea of what I'm trying to do, imagine something looking like this:
#define ARDUINO_READ_Q0 // Read pins 22-29 /n Return 1B
This way I can say "next line" without making the mess of having two lines per #define.
It's sort of a formatting preference. I'm about to have a lot of #defines.
If you are using Visual Studio 2013 there are special XML tags that you can use to do this.
/// <summary>Read pins 22-29</summary>
#define ARDUINO_READ_Q0
This will display "Read pins 22-29" in the Intellisense tooltip when you hover the ARDUINO_READ_Q0.
You can find more documentation details on MSDN:
http://msdn.microsoft.com/en-us/library/ms177227.aspx
http://msdn.microsoft.com/en-us/library/ms177226.aspx
Note: This may work on older version of Visual Studio but I only have 2013 have on my laptop at the moment.

Why MSVC compiler converts "??-" sequence to "~" in string literals?

I have a hard coded string in my code (which should be used as a file mask), but compiler always changes the "??-" sequence to "~", for example:
const wchar_t textW[] = L"test-??-??-??.txt";
The testW will be "test-~~??.txt" (without quotes).
The same happens for non-unicode strings as well:
const char textA[] = "test-????-??-??.txt";
textA will be "test-??~~??.txt" (without quotes).
My compiler is Microsoft Visual C++ 2008.
I have just tried this with Visual Studio 2013, the string in runtime is correct and intellisense displays the correct value on the tooltip when I'm tracing the app, but... But in the writing mode (when app isn't running) intellisense displays incorrect value with tildas on the tooltip.
That's a trigraph, a way to express characters that are not always available on keyboards.
This behavior is controlled by the /Zc:trigraphs option, which is off by default. It appears it is enabled for your project, I would suggest you disable it.
It's called a trigraph. They are replaced by the preprocessor.

Is there a TRACE statement for basic win32 C++?

In MFC C++ (Visual Studio 6) I am used to using the TRACE macro for debugging. Is there an equivalent statement for plain win32?
_RPTn works great, though not quite as convenient. Here is some code that recreates the MFC TRACE statement as a function allowing variable number of arguments. Also adds TraceEx macro which prepends source file and line number so you can click back to the location of the statement.
Update: The original code on CodeGuru wouldn't compile for me in Release mode so I changed the way that TRACE statements are removed for Release mode. Here is my full source that I put into Trace.h. Thanks to Thomas Rizos for the original:
// TRACE macro for win32
#ifndef __TRACE_H__850CE873
#define __TRACE_H__850CE873
#include <crtdbg.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef _DEBUG
#define TRACEMAXSTRING 1024
char szBuffer[TRACEMAXSTRING];
inline void TRACE(const char* format,...)
{
va_list args;
va_start(args,format);
int nBuf;
nBuf = _vsnprintf(szBuffer,
TRACEMAXSTRING,
format,
args);
va_end(args);
_RPT0(_CRT_WARN,szBuffer);
}
#define TRACEF _snprintf(szBuffer,TRACEMAXSTRING,"%s(%d): ", \
&strrchr(__FILE__,'\\')[1],__LINE__); \
_RPT0(_CRT_WARN,szBuffer); \
TRACE
#else
// Remove for release mode
#define TRACE ((void)0)
#define TRACEF ((void)0)
#endif
#endif // __TRACE_H__850CE873
From the msdn docs, Macros for Reporting:
You can use the _RPTn, and _RPTFn macros, defined in CRTDBG.H, to replace the use of printf statements for debugging. These macros automatically disappear in your release build when _DEBUG is not defined, so there is no need to enclose them in #ifdefs.
There is also OutputDebugString. However that will not be removed when compiling release.
Trace macros that provide messages with source code link, run-time callstack information, and function prototype information with parameter values:
Extended Trace: Trace macros for Win32
I just use something like this (from memory, not tested at all...)
#define TRACE(msg) {\
std::ostringstream ss; \
ss << msg << "\n"; \
OutputDebugString(msg.str()); \
}
And then I can write things like :-
TRACE("MyClass::MyFunction returned " << value << " with data=" << some.data);
You can wrap that in some #ifdefs to remove it in release builds easily enough.
I found that using the _RPT() macro will also work with a C source file in Visual Studio 2005. This article Debugging with Visual Studio 2005/2008: Logging and Tracing provides an overview of TRACE, _RPT, and other logging type macros.
I generate a line for a log file called the ASSRTLOG which contains logs and when writing the log to the file, I also do the following source code line:
_RPT1(_CRT_WARN, "ASSRTLOG: %s", szLog1);
This line puts the same log that is going into the log file into the output window of the Visual Studio 2005 IDE.
You might be interested in the mechanics behind the approach we are using for logging. We have a function PifLogAbort() which accepts a series of arguments that are then used to generate a log. These arguments include the name of the file where the log is being generated along with the line number. The macro looks like this:
#define NHPOS_ASSERT_TEXT(x, txt) if (!(x)) { PifLogAbort( (UCHAR *) #x , (UCHAR *) __FILE__ , (UCHAR *) txt , __LINE__ );}
and the function prototype for PifLogAbort() look like this:
PifLogNoAbort(UCHAR *lpCondition, UCHAR *lpFilename, UCHAR *lpFunctionname, ULONG ulLineNo)
and to use the macro we will insert a line like this:
NHPOS_ASSERT_TEXT(sBRetCode >= 0, "CliEtkTimeIn(): EtkTimeIn() returned error");
What this macro will do is that if the return code is less than 0 (the assertion fails), a log will be generated with the provided text. The log includes the condition that generated the log along with file name and line number.
The function PifLogAbort() generates logs with a specified length and treats the output file as a circular buffer. The logs have a time and date stamp as well.
In those cases where we want to generate the descriptive text dynamically at run time, perhaps to provide the actual error code value, we use the sprintf() function with a buffer as in the following code sequence:
if (sErrorSave != STUB_BM_DOWN) {
char xBuff[128];
sprintf(xBuff, "CstSendBMasterFH: CstComReadStatus() - 0x%x, sError = %d", usCstComReadStatus, CliMsg.sError);
NHPOS_ASSERT_TEXT((sErrorSave == STUB_BM_DOWN), xBuff);
}
If we want the logs to not be generated, all we need to do is to go to the single header file where the macro is defined and define it to be nothing then recompile. However we have found that these logs can be very valuable when investigating field issues and are especially useful during integration testing.
Windows Events are a potential replacement for TRACE macros, depending on your particular scenario. The code gets compiled into both Debug and Release configurations. Event tracing can then be dynamically enabled and disabled, displayed in real-time, or dumped on a client's machine for later diagnosis. The traces can be correlated with trace information gathered from other parts of the OS as well.
If you merely need to dump information whenever code reaches certain checkpoints, together with variable content, stack traces, or caller names, Visual Studio's Tracepoints are a non-intrusive option to do so.