Showing posts with label C/Cpp. Show all posts
Showing posts with label C/Cpp. Show all posts

Friday, July 26, 2024

Automating MSVC builds

While rewritting a few of my personal tools from Rust back to C++, I found myself willing to automate the build process. At first, I tried to invoke MSVC’s cl compiler directly, but it has proven to be absolute hell to do.

Eventually I stumbled upon the marvellous MSBuild tool, which is capable of understanding the .sln file and take all compiler and linker options from it:

msbuild foo.sln /p:Configuration=Release /p:Platform=x64

With that, I finally had the script to automate one build:

call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
set APP="vscode-font-patch"
msbuild %APP%.sln /p:Configuration=Release /p:Platform=x64
move /Y x64_Release\%APP%.exe "D:\Stuff\apps\_audio tools\"
rmdir /S /Q x64_Release
pause

Then it was time to automate the release build of all my listed projects. And I found out how awkward .bat syntax is. Loop syntax is particularly horrifying. In the end, I was able to cook a script to automate my C++ builds:

call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"

set APPS[0]="vscode-font-patch"

set "i=0"
:SymLoop
if not defined APPS[%i%] goto :EndLoop
call set APP=%%APPS[%i%]%%
cd %APP%
echo Building %APP%...
msbuild %APP%.sln /p:Configuration=Release /p:Platform=x64
move /Y x64_Release\%APP%.exe "D:\Stuff\apps\_audio tools\"
rmdir /S /Q x64_Release
cd ..

set /a "i+=1"
goto :SymLoop
:EndLoop
pause

Friday, July 12, 2024

C++20 variadics with abbreviated function template

Today, when working with my stripped C++ Win32 library – after the frustration with Rust’s long compile times in WinSafe –, I was trying to implement an overloaded variadic method, in order to get rid of initializer_list. Then I stumbled upon a great article which introduced me to the abbreviated function template feature of C++20, which I’m using.

This is an example:

int foo(std::wstring n)
{
	OutputDebugStringW(n.data());
	OutputDebugStringW(L"\n");
	return 43;
}

int foo(std::wstring n, std::convertible_to<std::wstring> auto... nn)
{
	foo(n);
	return foo(nn...);
}

The convertible_to concept is particularly interesting in narrowing the template type.

Thursday, July 21, 2022

Sizes of Windows integral types

While developing WinSafe, it’s very common to convert the Windows integral data types to their Rust equivalent. Care must be taken, however, when it comes to pointer size, which varies according to the architecture. Since WinSafe is aimed to both 32 and 64-bit Windows, I must pay attention.

For reference, below is the table I’m using to figure out the sizes:

Signed C Signed Rust Unsigned C Unsigned Rust 32-bit 64-bit
CHAR
 
 
i8 UCHAR
BYTE
BOOLEAN
u8 8 bit (1 byte)
SHORT
 
 
i16 USHORT
WCHAR
WORD
u16 16 bit (2 byte)
BOOL
INT
LONG
 
i32  
UINT
ULONG
DWORD
u32 32 bit (4 byte)
INT_PTR
LONG_PTR
LPARAM
 
isize UINT_PTR
ULONG_PTR
WPARAM
SIZE_T
usize 32 bit (4 byte) 64 bit (8 byte)
LARGE_INTEGER
LONG64
LONGLONG
 
 
i64 ULARGE_INTEGER
ULONG64
ULONGLONG
DWORD64
DWORDLONG
QWORD
u64 64 bit (8 byte)

The table above is an extension of this one.

Friday, September 17, 2021

My Visual C++ 2019 settings

Just for the record, these are the settings I’m always using with Visual Studio 2019, when creating a new, empty C++ project:

  • General
    • Output Directory: $(SolutionDir)$(Platform)_$(Configuration)\
    • Intermediate Directory: $(Platform)_$(Configuration)\
    • C++ Language Standard: ISO C++20 Standard (/std:c++20)
  • C/C++
    • General
      • Debug Information Format: None (Release)
      • Treat Warning As Errors: Yes (/WX) (Release)
      • Multi-processor Compilation: Yes (/MP)
    • Code Generation
      • Runtime Library: Multi-threaded (/MT) (Release)
  • Linker
    • Debugging
      • Generate Debug Info: No (Release)
    • System
      • SubSystem: Windows (/SUBSYSTEM:WINDOWS)

As of April 2024, the settings above also apply to Visual Studio 2022.

Thursday, May 13, 2021

The ghastly button focus

During my 20 years or so writing Win32 programs, I always relied on SetFocus to focus a control. However, I always noticed a weird behavior on push buttons regarding the BS_DEFPUSHBUTTON style, which was never right. In fact, I remember one of the past WinLamb incarnations which I implemented some trick involving changing the button style when setting the focus.

Anyway, now I found out how to properly set the focus on a control, and it does not involve SetFocus, but rather the WM_NEXTDLGCTL message:

SendMessage(hParent, WM_NEXTDLGCTL, (WPARAM)hButton, MAKELPARAM(TRUE, 0));

And the push button magically sets its own style correctly.

Friday, October 16, 2020

Validating lambda signatures in C++17

WinLamb, as the name itself implies, is heavily based on lambda functions. While searching a way to enforce the lambda signatures in the upcoming C++17 release, I received an incredible answer on StackOverflow:

#include <functional>
#include <type_traits>
	
template<typename F>
auto foo(F&& func) noexcept ->
	std::enable_if_t<
		std::is_same_v<
			decltype(std::function{std::forward<F>(func)}),
			std::function<void(int)>
		>, void
	>
{
	func(33);
}

Up to this point, I was completely unaware of the existence of trailing return types in function declarations.

The validation is extremely restrict, serving my purposes perfectly. And it seems that the upcoming C++20 concepts feature can simplify it quite a lot.

Thursday, August 6, 2020

SFINAE and enable_if

Today, while researching for the upcoming C++17 version of WinLamb, I was rethinking the idea of restricting the allowed types on a template argument. That’s an SFINAE thing, scary to many people – including me sometimes, in my love-hate relationship with advanced C++ stuff.

The thing is that I ended up writing a working piece of code using std::enable_if to restrict a template argument, and I’m quite proud of it.

#include <type_traits>

struct One { int num; };
struct Two { int num; };
struct Tre { int num; };

template<
  typename T,
  typename = std::enable_if_t<
    std::is_same_v<T, One> ||
    std::is_same_v<T, Two>
  >
>
void foo(T& o) { ++o.num; }

int main() {
  One o;
  foo(o);
  return 0;
}

In the code above, One and Two classes will work with foo(), whereas Tre will not compile, despite being exactly like the others.

Wednesday, February 5, 2020

False memory leak reports of static objects

I was having a weird memory leak report in a C++ program, happening right after I close it, and triggered by a call to _CrtDumpMemoryLeaks, which exists in the very end of WinMain function in WinLamb. I was puzzled, because I’ve commented everything out, and I still had the memory leak.

Turns out _CrtDumpMemoryLeaks is called at the end of WinMain, before the static object destructors are called. And there you go: if any statically allocated object had made a heap allocation, the memory won’t be freed yet, thus the report.

I’m not the only one with this problem, but so far no solution had any effect. By now I’ll just avoid static allocation of objects which alloc memory on the heap, and carry on with life. Maybe I’m too used to the JavaScript blessings.

Thursday, February 7, 2019

A very simple, raw Win32 WinLamb program

Months ago I noticed that WinLamb was missing a simple, introductory example. I never really had time to write and publish one. Until today.

Click lines is a very simple program, inspired by Charles Petzold, which draws lines upon mouse clicks. Just this. It’s intended to be a very simple showcase of WinLamb, showing how to create raw windows, raw custom controls, and handling messages. I usually use dialog boxes on my real-world programs, but for this one I really kept it bare-bones, with no dialogs.

I hope it can be useful to anyone interested in WinLamb.

Sunday, October 21, 2018

SRTEd 1.3.1, minor release

This week I released a new SRTEd version 1.3.1, with has minor, but many usability improvements. Also, it’s built with latest version of WinLamb, my very own personal raw Win32 library, which I use for everything.

I was planning a bigger release for SRTEd, with more advanced features, but since my time is pretty short these days, I just released a version where it is now, with the UI improvements. It’s already more than a year since the last version, time flies. One notable difference is the absence of a 32-bit executable, which was not included because it was firing false positives for malware, something completely absurd. To avoid the hassle, I opted to keep only the 64-bit version.

SRTEd can be downloaded from CNET.

Friday, February 16, 2018

Alternative approach to bitflags in C++

Just wondering about a short, expressive and alternative way to implement bitflags in C++11.

Right now I don’t plan to adopt this idiom, but it doesn’t look so bad.

Saturday, December 9, 2017

A C++ container which keeps insertion order

C++ is a poorly designed programming language, and I live a love-hate relatioship with it.

On my vacation days, when working on WinLamb for the next version of SRTEd, I needed a container to keep track of the order the elements were inserted. Among the many useless obscure things that C++ has, it doesn’t have such a container. So I had to write one, which after much struggle I named it the insert_order_map.

Usage example, including iterator support for C++11 range-based for loop:

insert_order_map<wstring, wstring> all = {
  { L"initial", L"blab" },
  { L"initial2", L"bleb" }
};

all[L"first"] = L"abcdef";
all[L"second"] = L"123456";

for (insert_order_map<wstring, wstring>::entry& e : all) {
  wstring key = e.key;
  wstring val = e.value;
}

At first I wondered about using a sentinel linear search, line the one used within store. But then I realized that 99% of the time I’ll be using a string as the key with few elements inserted, thus the initial copy of the string at each search would take away the performance gains of the sentinel algorithm. So I decided to stick to an ordinary linear search.

Tuesday, April 4, 2017

After 4 years, SRTEd 1.3.0

So finally I released a new version of SRTEd, my own subtitles editor. Honestly, in these four years I didn’t see a better subtitle editor, I still think it’s the most user-friendly editor out there.

The interface didn’t improve much, but there are many bugfixes and minor UI adjusts. It took so long because I entirely rewrote it using my new Win32 library, which I expect to release as open source soon, together with an article explaining what it is and how to take the best out of it.

It can be downloaded from CNET or Softpedia.

Sunday, May 1, 2016

Git .gitignore file to Visual C++ 2015 Update 2

After upgrading my Visual C++ 2015 from Update 1 to Update 2, I noticed that a new file appeared in the root directory of the projects I was opening. The file was always named ProjectName.VC.db. Indeed according to the release notes, a new SQLite-based database engine is now being used by default, and that’s the file where the database is stored. The old file, named ProjectName.sdf is now unused and can be safely deleted.

The change also demanded an update on my .gitignore files to also ignore this new database file, and here it goes:
Debug/
Release/
*.aps
*.db
*.ffs_db
*.ncb
*.opensdf
*.rar
*.sdf
*.suo
*.user
*.VC.opendb
TODO.txt
If you import and old .vssettings file, however, the option to use the new SQLite-based database can be rolled back to the old .sdf files. To manually change it, go to: Tools → Options → Text Editor → C/C++ → Advanced → Browsing/Navigation → Enable New Database Engine. Set it to “true”.

Wednesday, March 23, 2016

Disabling C++ exceptions in Visual Studio 2015

When using the STL with Visual Studio 2015 – and older versions, probably –, C++ exceptions are enabled by default. To view the options specified below, first add at least one CPP file to your project.

The first thing to change on the project settings is under C/C++ code generation, enable C++ exceptions: set this to “no”.

Then, on the project settings, C/C++ preprocessor, to each configuration and platform individually, add the following preprocessor definition:
_HAS_EXCEPTIONS=0
This way you’ll be able to use the STL without the C++ exception handling mechanism.

Wednesday, December 30, 2015

Evernote abandons C# in favor of C++

It’s with a feeling of “I knew it already” that I read this note, from 2010, where Evernote team abandons C# and rewrite the whole thing from scratch in C++. It’s not that C++ is a good language – it’s awful – but the point is that this whole managed code hype destroys any hopes of performance one may have. I’ve seen benchmarks comparing raw loops and things that doesn’t matter, when in fact the problem is the huge runtime needed for these programs to run, which slows everything down and eats a lot memory. The point is that managed programs, specially WPF stuff that Evernote used, just can’t beat native ones.

Technically, C# is a beautifully designed language, but in real world its programs are slow and sluggish. C++ is a horrible language, but being compiled directly to native code, generates optimized programs. Evernote guys just realized that.

Saturday, June 14, 2014

Named arguments in C

When experimenting with some C99 features of C, I found a very cool trick to have named parameters, using a feature called designated initializers. The first time I read about designated initializers I must admit I found it to be pretty useless, but as I started testing it out, I ended up finding it very useful, since it can make code a lot more readable. Using it together with variadic macros, it was possible to have a very clean named parameter system.

Straight into the code, this is the technique:
typedef struct { int year; const wchar_t *name; } Foo_args; // parameters
void Foo_func(Foo_args args) {
	int x = args.year + 10; // use the argument
}
#define Foo(...) Foo_func((Foo_args){ __VA_ARGS__ })
And this is how you call the function:
Foo(.year = 2014, .name = L"Rodrigo");
The function calling is clear, and its implementation doesn’t add much noise to the code: I believe the price is payable and the result is worth.

Friday, March 28, 2014

A simple alternative to C++ exceptions

I’ve been doing a lot of C++11 research and coding ultimately, and I’m still upset with the C++ exceptions. When reading the concepts, it seems to be a reasonably good alternative to simply return a boolean, but as you try to stuff it in your code, you begin to feel like manipulating a stressed hedgehog. And it’s very frustrating, since you have to stop thinking about your code – what really matters –, to think about the implications of the code you are writing upon the code itself.

Usually, my needs are really simple, I just need an extended way to report a success or a failure from a function. I never wrote something that really needed to tackle differents kinds of errors: it’s just success, or failure with a reason, which usually popped in an alert message box.

After quitting the exceptions, when trying to solve this problem, my first move was to use an extra string pointer as the last parameter to hold eventual error messages. It goes like this:
bool Func(int p1, int p2, wstring *pErr=nullptr) {
	if(false) {
		if(pErr) *pErr = L"Error message.";
		return false;
	}
	if(pErr) *pErr = L""; // all good
	return true;
}

bool Second(float nn, wstring *pErr=nullptr) {
	if(!Func(42, 1337, pErr)) { // will return error message from inner function
		return false;
	} else if(false) {
		if(pErr) *pErr = L"Another error.";
		return false;
	}
	if(pErr) *pErr = L""; // all good
	return true;
}

{
	wstring err;
	if(!Func(42, 1337, &err))
		scream(err.c_str());
}
There is no problem with this approach, and I used it for quite some time. It is clear, and one would have no doubts about what is going on. It is, however a bit cumbersome to write all those pErr checks. So at some point I started considering something else.

My second approach was to use a standard pair as the return type to the function. Something like this:
pair<bool, wstring> Func() {
	if(false)
		return make_pair(false, L"Error description message.");
	return make_pair(true, L"");
}

{
	pair<bool, wstring> ret = Func();
	if(!ret.first)
		scream(ret.second.c_str());
}
I never really used this. It doesn’t look clear enough, and the declaration of the pair variable, just to hold the return value, doesn’t amuse me.

Then I start thinking about writing a “bool on steroids” class, specifically overloading the operator bool, so there would be no need to declare a variable just to hold the result value of the invoked function. This is the class:
#include <string>

class Failed {
public:
	Failed(bool allGood)                   : _hasFailed(!allGood) { }
	explicit Failed(std::wstring reason)   : _hasFailed(true), _reason(reason) { }
	explicit Failed(const wchar_t *reason) : _hasFailed(true), _reason(reason) { }
	virtual ~Failed()                      { }
	operator bool() const         { return _hasFailed; }
	const wchar_t* reason() const { return _reason.c_str(); }
private:
	bool _hasFailed;
	std::wstring _reason;
};
And this is the usage:
Failed Func() {
	if(false)
		return Failed(L"This function failed.");
	return true;
}

Failed Second() {
	if(Failed f = Func()) { // if Func() returned false
		return f; // return from inner function
	} else if(false) {
		return Failed(L"Another error message.");
	}
	return true;
}

{
	if(Failed f = Second())
		scream(f.reason());
}
This approach looks a lot elegant to me. It’s clean, allows the chaining of error messages, and it even allows the inheriting of the Failed class to add more specific error data – although I never really needed this.

The only thing which makes me uncomfortable with this class is the _hasFailed member, which holds a reversed boolean value of the object meaning: if there’s a success, it’s false; if there’s a failure, it’s true. I implemented it this way so that I could use a declaration of the class within an if statement, with no need to declare a variable just to hold the result, as I did on the previous example when I returned a standard pair. Also, it explains why I chose the name “Failed” instead of something like “BigBool”: to explicit the idea of a failure being handled by the if.

Other than that, I consider it a neat approach, and that’s the best solution I could come up with so far.

Tuesday, December 17, 2013

Creating project templates for Visual Studio 2013

There are a couple of project settings that I set for every native C++ Win32 project I want to start, basically, more aggressive optimizations for the release build.

Right now, messing around with my brand new Visual Studio 2013 – which I’m appreciating so far –, I discovered how to create a template project with all the settings I need, including subfolders and files. I found this article which explains the process for an ASP.NET MVC project, but the steps are the same for a C++ one.

The templates are exported as ordinary ZIP files, and importing existing ones is trivial, you just need to copy this ZIP file into the base directory. On my computer, this is the full path for the custom user templates:
C:\Users\Rodrigo\Documents\Visual Studio 2013\Templates\ProjectTemplates
In addition to the project settings, I also put in the template a subdirectory called “src”, my very basic main.cpp file, which contains my wWinMain entry point. It seems that I’ll never have to write it again.

Monday, December 16, 2013

A simple C++ smart pointer class

Until I started using move semantics of C++11, I used this smart pointer class, which is template-based, heavily relies on operator overloading, and uses an instance counter:
template<typename T> class Ptr {
public:
	Ptr()                 : _ptr(NULL), _counter(NULL) { }
	Ptr(T *ptr)           : _ptr(NULL), _counter(NULL) { operator=(ptr); }
	Ptr(const Ptr& other) : _ptr(NULL), _counter(NULL) { operator=(other); }
	~Ptr() {
		if(_counter && !--(*_counter)) {
			delete _ptr;     _ptr = NULL;
			delete _counter; _counter = NULL;
		}
	}
	Ptr& operator=(T *ptr) {
		this->~Ptr();
		if(ptr) {
			_ptr = ptr; // take ownership
			_counter = new int(1); // start counter
		}
		return *this;
	}
	Ptr& operator=(const Ptr& other) {
		if(this != &other) {
			this->~Ptr();
			_ptr = other._ptr;
			_counter = other._counter;
			if(_counter) ++(*_counter);
		}
		return *this;
	}
	bool isNull() const         { return _ptr == NULL; }
	T& operator*()              { return *_ptr; }
	const T* operator->() const { return _ptr; }
	T* operator->()             { return _ptr; }
	operator T*() const         { return _ptr; }
private:
	T   *_ptr;
	int *_counter;
};
Example usage:
struct When {
	int month;
	int day;
};

Ptr<When> GetLunchTime()
{
	Ptr<When> ret = new When(); // alloc pointer to be owned
	ret->month = 12;
	ret->day = 16;
	return ret;
}

int main()
{
	Ptr<When> lunchTime = GetLunchTime();
	// ...
	// no need to delete lunchTime
	return 0;
}
It works fine, but with the implementation of move semantics – which is truly great –, it seems that I don’t need it anymore. So I’m publishing it here for historical reasons.