Full Width [alt+shift+f] FOCUS MODE Shortcuts [alt+shift+k]
Sign Up [alt+shift+s] Log In [alt+shift+l]
41
When writing portable C++ code you need to write conditional code that depends on compiler used or the OS for which the code is written. Here’s a typical case: #if defined (_MSC_VER) // code specific to Visual Studio compiler #endif To perform those checks you need to check pre-processor macros that various compilers set. It can either be binary is defined vs. is not defined check (e.g. __APPLE__) or checking a value of the macro (e.g. _MSC_VER defines version of Visual Studio compiler). This document describes macros set by various compilers. Other documentations: predefined macros in Visual Studio https://sourceforge.net/p/predef/wiki/Compilers/ to list clang’s pre-defined macros: clang -x c /dev/null -dM -E to list gcc’s pre-defined macros: gcc -x c /dev/null -dM -E (not that on mac gcc is actually clang that ships with XCode) the -x c /dev/null -dM -E also works for mingw (which is based on gcc) listing predefined macros for other compilers Checking for OS...
over a year ago

Comments

Improve your reading experience

Logged in users get linked directly to articles resulting in a better reading experience. Please login for free, it takes less than 1 minute.

More from Krzysztof Kowalczyk blog

Ideas for faster web dev cycle

I strongly believe that fast iteration cycle is important for productivity. In programming fast iteration means: how quickly can I go from finishing writing the code to testing it. That’s why I don’t like languages that compile slowly: slow compilation puts a hard limit on your iteration cycle. That’s a general principle. How does it translate to actions? I’m glad you asked. Simulated errors I’m writing a web app and some code paths might fail e.g. server returns an error response. When that happens I want to display an error message to the user. I want to test that but server doesn’t typically return errors. I can modify the server to return error and restart it but in a compiled language like Go it’s a whole thing. Instead I can force error condition in the code. Because web dev typically offers hot reload of code, I can modify the code to pretend the request failed, save the code, reload the app and I’m testing the error handling. To make it less ad-hoc another strategy is to have debug flags on window object e.g.: window.debug.simulateError = false Then the code will have: try { if (window.debug.simulateError) { throw Error("fetch failed"); } let rsp = await fetch(...); } That way I can toggle window.debug.simulateError in dev tools console, without changing the code. I have to repeat this code for every fetch(). More principled approach is: async function myFetch(uri, opts) { if (window.debug.simulateError) { throw new Error("featch failed"); } return await fetch(uri, opts); } To go even further, we could simulate different kinds of network errors: Response.ok is false response is 404 or 500 failed to reach the server We can change simulateError from bool to a number and have: async function myFetch(uri, opts) { let se = window.debug.simulateError; if (se === 1) { // simulate Response.ok is false return ...; } if (se === 2) { // simulate 404 response return; } if (se === 3) { // simulate network offline } return await fetch(uri, opts); } Start by show dialog Let’s say I’m working on a new dialog e.g. rename dialog. To get to that dialog I have to perform some UI action e.g. use context menu and click the Rename note menu item. Not a big deal but I’m still working on the dialog so it’s a bit annoying to repeat that UI action every time I move the button to the right, to see how it’ll look. In Svelte we do: let showingRenameDialog = $state(false); function showRenameDialog() { showingRenameDialog = true; } {#if showingRenameDialog} <RenameDialog ...></RenameDialog> {'if} To speed up dev cycle: let showingRenameDialog = $state(true); // show while we're working ont While I’m still designing and writing code for the dialog, show it by default. That way app reloads due to changing code won’t require you to manually redo UI actions to trigger the dialog. Ad-hoc test code Let’s say you’re writing a non-trivial code server code to process a request. Let’s say the request is a POST with body containing zip file with images which the server needs to unzip, resize the files, save them to a file system. You want to test it as you implement the logic but iteration cycle is slow: you write the code recompile and restart the server go through UI actions to send the request Most of the code (unpacking zip file, resizing images) can be tested without doing the request. So you isolate the function: func resizeImagesInZip(zipData []byte) error { // the code you're writing on } Now you have to trigger it easily. The simplest way is ad-hoc test code: func main() { if true { zipData := loadTestZipFileMust() resizeImagesInZip(zipData); return; } } While you’re working on the code, the server just runs the test code. When you’re done, you switch it off: func main() { if false { // leave the code so that you can re-enable it // easily in the future zipData := loadTestZipFileMust() resizeImagesInZip(zipData); return; } } Those are few tactical tips to increase dev cycles. You can come up with more such ideas by asking yourself: how can I speed iteration cycle?

a month ago 22 votes
Stage manager in Mac OS

Stage Manager in Mac OS is not a secret, but I’ve only learned about it recently. It’s off by default so you have to enable it in system settings: It’s hard to describe in words, so you’ll have to try it. And experiment a bit because I didn’t get in the first hour. It’s a certain way to manage windows for less clutter. Imagine you have a browser, an editor and a terminal i.e. 3 windows. Might be annoying to have them all shown on screen. When Stage Manager is enabled, thumbnails of windows are on the left edge of the screen and you can switch to the window by clicking the thumbnail. By default Stage Manager shows each window by itself on screen. You can group them by dragging thumbnail onto screen. For example, when I’m developing, I’m using text editor and terminal so I will group them so they are both visible on screen at the same time, but not the other apps. So far I’m enjoying using Stage Manager.

a month ago 22 votes
Zed debug setup for go server / Svelte web app

Today I figured out how to setup Zed to debug, at the same time, my go server and Svelte web app. My dev setup for working on my web app is: go server is run with -run-dev arg go server provides backend apis and proxies requests it doesn’t handle to a vite dev server that does the serving of JavaScript etc. files from my Svelte code go server in -run-dev mode automatically launches vite dev go server runs on port 9339 It’s possible to setup Zed to debug both server and frontend JavaScript code. In retrospect it’s simple, but took me a moment to figure out. I needed to create the following .zed/debug.json: // Project-local debug tasks // // For more documentation on how to configure debug tasks, // see: https://zed.dev/docs/debugger [ { "adapter": "Delve", "label": "run go server", "request": "launch", "mode": "debug", "program": ".", "cwd": "${ZED_WORKTREE_ROOT}", "args": ["-run-dev", "-no-open"], "buildFlags": [], "env": {} }, { "adapter": "JavaScript", "label": "Debug in Chrome", "type": "chrome", "request": "launch", "url": "http://localhost:9339/", "webRoot": "$ZED_WORKTREE_ROOT/src", "console": "integratedTerminal", "skipFiles": ["<node_internals>/**"] } ] It’s mostly self-exploratory. First entry tells Zed to build go program with go build . and run the resulting executable under the debugger with -run-dev -no-open args. Second entry tells to launch Chrome in debug mode with http://localhost:9339/ and that files seen by Chrome come from src/ directory i.e. if browser loads /foo.js the source file is src/foo.js. This is necessary to be able to set breakpoints in Zed and have them propagate to Chrome. This eliminates the need for terminal so I can edit and debug with just Zed and Chrome. This is a great setup. I’m impressed with Zed.

a month ago 30 votes
lazy import of JavaScript modules

When working on big JavaScript web apps, you can split the bundle in multiple chunks and import selected chunks lazily, only when needed. That makes the main bundle smaller, faster to load and parse. How to lazy import a module? let hljs = await import("highlight.js").default; is equivalent of: import hljs from "highlight.js"; Now:   let libZip = await import("@zip.js/zip.js");   let blobReader = new libZip.BlobReader(blob); Is equivalent to: import { BlobReader } from "@zip.js/zip.js"; It’s simple if we call it from async function but sometimes we want to lazy load from non-async function so things might get more complicated: let isLazyImportng = false; let hljs; let markdownIt; let markdownItAnchor; async function lazyImports() { if (isLazyImportng) return; isLazyImportng = true; let promises = await Promise.all([ import("highlight.js"), import("markdown-it"), import("markdown-it-anchor"), ]); hljs = promises[0].default; markdownIt = promises[1].default; markdownItAnchor = promises[2].default; } We can run it from non-async function: function doit() { lazyImports().then( () => { if (hljs) { // use hljs to do something } }) } I’ve included protection against kicking of lazy import more than once. That means on second and n-th call we might not yet have the module loaded so hljs will be still undefined.

a month ago 22 votes
Using await in Svelte 5 components

Svelte 5 just added a way to use async function in components. This is from Rich Harris talk The simplest component <script> async function multiply(x, y) { let uri = `/multiply?x=${x}&y=${y}` let rsp = await fetch(uri) let resp = await rsp.text(); return parseInt(resp); } let n = $state(2) </script> <div>{n} * 2 = {await multiply(n, 2)}</div> Previously you couldn’t do {await multiply(n, 2) because Svelte didn’t understand promises. Now you can. Aborting outdated requests Imagine getting search results from a server based on what you type in an input box. If you type foo, we first send request for f, then for fo then for foo at which point we don’t care about the results for f and fo. Svelte 5 can handle aborting outdated requests: <script> import { getAbortSignal } from "svelte"; let search = $state("") const API = "https://dummyjson.com/product/search"; const response = $derived(await fetch(`${API}?q=${search}`), { signal: getAbortSignal() }) </script> <input bind:value={search}> <svelte:boundary> <ul> {#each (await response.json().products as product)} <li>{product.title}</li> {/each} </ul>

a month ago 23 votes

More in programming

Understanding Bazel remote caching

A deep dive into the Action Cache, the CAS, and the security issues that arise from using Bazel with a remote cache but without remote execution

4 hours ago 2 votes
Apologies and forgiveness

The first in a series of posts about doing things the right way

3 hours ago 2 votes
Trying to Make Sense of Casing Conventions on the Web

(I present to you my stream of consciousness on the topic of casing as it applies to the web platform.) I’m reading about the new command and commandfor attributes — which I’m super excited about, declarative behavior invocation in HTML? YES PLEASE!! — and one thing that strikes me is the casing in these APIs. For example, the command attribute has a variety of values in HTML which correspond to APIs in JavaScript. The show-popover attribute value maps to .showPopover() in JavaScript. hide-popover maps to .hidePopover(), etc. So what we have is: lowercase in attribute names e.g. commandfor="..." kebab-case in attribute values e.g. show-popover camelCase for JS counterparts e.g. showPopover() After thinking about this a little more, I remember that HTML attributes names are case insensitive, so the browser will normalize them to lowercase during parsing. Given that, I suppose you could write commandFor="..." but it’s effectively the same. Ok, lowercase attribute names in HTML makes sense. The related popover attributes follow the same convention: popovertarget popovertargetaction And there are many other attribute names in HTML that are lowercase, e.g.: maxlength novalidate contenteditable autocomplete formenctype So that all makes sense. But wait, there are some attribute names with hyphens in them, like aria-label="..." and data-value="...". So why isn’t it command-for="..."? Well, upon further reflection, I suppose those attributes were named that way for extensibility’s sake: they are essentially wildcard attributes that represent a family of attributes that are all under the same namespace: aria-* and data-*. But wait, isn’t that an argument for doing popover-target and popover-target-action? Or command and command-for? But wait (I keep saying that) there are kebab-case attribute names in HTML — like http-equiv on the <meta> tag, or accept-charset on the form tag — but those seem more like legacy exceptions. It seems like the only answer here is: there is no rule. Naming is driven by convention and decisions are made on a case-by-case basis. But if I had to summarize, it would probably be that the default casing for new APIs tends to follow the rules I outlined at the start (and what’s reflected in the new command APIs): lowercase for HTML attributes names kebab-case for HTML attribute values camelCase for JS counterparts Let’s not even get into SVG attribute names We need one of those “bless this mess” signs that we can hang over the World Wide Web. Email · Mastodon · Bluesky

yesterday 5 votes
The Angels and Demons of Nondeterminism

Greetings everyone! You might have noticed that it's September and I don't have the next version of Logic for Programmers ready. As penance, here's ten free copies of the book. So a few months ago I wrote a newsletter about how we use nondeterminism in formal methods. The overarching idea: Nondeterminism is when multiple paths are possible from a starting state. A system preserves a property if it holds on all possible paths. If even one path violates the property, then we have a bug. An intuitive model of this is that for this is that when faced with a nondeterministic choice, the system always makes the worst possible choice. This is sometimes called demonic nondeterminism and is favored in formal methods because we are paranoid to a fault. The opposite would be angelic nondeterminism, where the system always makes the best possible choice. A property then holds if any possible path satisfies that property.1 This is not as common in FM, but it still has its uses! "Players can access the secret level" or "We can always shut down the computer" are reachability properties, that something is possible even if not actually done. In broader computer science research, I'd say that angelic nondeterminism is more popular, due to its widespread use in complexity analysis and programming languages. Complexity Analysis P is the set of all "decision problems" (basically, boolean functions) can be solved in polynomial time: there's an algorithm that's worst-case in O(n), O(n²), O(n³), etc.2 NP is the set of all problems that can be solved in polynomial time by an algorithm with angelic nondeterminism.3 For example, the question "does list l contain x" can be solved in O(1) time by a nondeterministic algorithm: fun is_member(l: List[T], x: T): bool { if l == [] {return false}; guess i in 0..<(len(l)-1); return l[i] == x; } Say call is_member([a, b, c, d], c). The best possible choice would be to guess i = 2, which would correctly return true. Now call is_member([a, b], d). No matter what we guess, the algorithm correctly returns false. and just return false. Ergo, O(1). NP stands for "Nondeterministic Polynomial". (And I just now realized something pretty cool: you can say that P is the set of all problems solvable in polynomial time under demonic nondeterminism, which is a nice parallel between the two classes.) Computer scientists have proven that angelic nondeterminism doesn't give us any more "power": there are no problems solvable with AN that aren't also solvable deterministically. The big question is whether AN is more efficient: it is widely believed, but not proven, that there are problems in NP but not in P. Most famously, "Is there any variable assignment that makes this boolean formula true?" A polynomial AN algorithm is again easy: fun SAT(f(x1, x2, …: bool): bool): bool { N = num_params(f) for i in 1..=num_params(f) { guess x_i in {true, false} } return f(x_1, x_2, …) } The best deterministic algorithms we have to solve the same problem are worst-case exponential with the number of boolean parameters. This a real frustrating problem because real computers don't have angelic nondeterminism, so problems like SAT remain hard. We can solve most "well-behaved" instances of the problem in reasonable time, but the worst-case instances get intractable real fast. Means of Abstraction We can directly turn an AN algorithm into a (possibly much slower) deterministic algorithm, such as by backtracking. This makes AN a pretty good abstraction over what an algorithm is doing. Does the regex (a+b)\1+ match "abaabaabaab"? Yes, if the regex engine nondeterministically guesses that it needs to start at the third letter and make the group aab. How does my PL's regex implementation find that match? I dunno, backtracking or NFA construction or something, I don't need to know the deterministic specifics in order to use the nondeterministic abstraction. Neel Krishnaswami has a great definition of 'declarative language': "any language with a semantics has some nontrivial existential quantifiers in it". I'm not sure if this is identical to saying "a language with an angelic nondeterministic abstraction", but they must be pretty close, and all of his examples match: SQL's selects and joins Parsing DSLs Logic programming's unification Constraint solving On top of that I'd add CSS selectors and planner's actions; all nondeterministic abstractions over a deterministic implementation. He also says that the things programmers hate most in declarative languages are features that "that expose the operational model": constraint solver search strategies, Prolog cuts, regex backreferences, etc. Which again matches my experiences with angelic nondeterminism: I dread features that force me to understand the deterministic implementation. But they're necessary, since P probably != NP and so we need to worry about operational optimizations. Eldritch Nondeterminism If you need to know the ratio of good/bad paths, the number of good paths, or probability, or anything more than "there is a good path" or "there is a bad path", you are beyond the reach of heaven or hell. Angelic and demonic nondeterminism are duals: angelic returns "yes" if some choice: correct and demonic returns "no" if !all choice: correct, which is the same as some choice: !correct. ↩ Pet peeve about Big-O notation: O(n²) is the set of all algorithms that, for sufficiently large problem sizes, grow no faster that quadratically. "Bubblesort has O(n²) complexity" should be written Bubblesort in O(n²), not Bubblesort = O(n²). ↩ To be precise, solvable in polynomial time by a Nondeterministic Turing Machine, a very particular model of computation. We can broadly talk about P and NP without framing everything in terms of Turing machines, but some details of complexity classes (like the existence "weak NP-hardness") kinda need Turing machines to make sense. ↩

yesterday 5 votes
Announcing the 2025 TokyoDev Developers Survey

The 2025 edition of the TokyoDev Developer Survey is now live! If you’re a software developer living in Japan, please take a few minutes to participate. All questions are optional, and it should take less than 10 minutes to complete. The survey will remain open until September 30th. Last year, we received over 800 responses. Highlights included: Median compensation remained stable. The pay gap between international and Japanese companies narrowed to 47%. Fewer respondents had the option to work fully remotely. For 2025, we’ve added several new questions, including a dedicated section on one of the most talked-about topics in development today: AI. The survey is completely anonymous, and only aggregated results will be shared—never personally identifiable information. The more responses we get, the deeper and more meaningful our insights will be. Please help by taking the survey and sharing it with your peers!

yesterday 8 votes