📅 Day 12: 𝒑𝒓𝒊𝒏𝒕𝒇 is 53 years old. cout chaining is an eyesore. C++20 finally fixed string formatting. We've all written it. The cout chain that wraps across three lines just to print two values. Or the 𝒑𝒓𝒊𝒏𝒕𝒇 format string, where a single wrong specifier %𝒅 instead of %𝒍𝒅 silently corrupts your output or crashes at runtime. No compiler warning. No type checking. Just undefined behavior waiting to happen. 𝒔𝒕𝒅::𝒇𝒐𝒓𝒎𝒂𝒕 lands in C++20 and changes everything. Python-style {} placeholders, fully type-safe, no format specifiers to memorize. The compiler knows what type you're passing. It formats it correctly. End of story. And it's not just cleaner, it's faster. iostream carries significant overhead from locale handling and the synchronized stream machinery. 𝒔𝒕𝒅::𝒇𝒐𝒓𝒎𝒂𝒕 skips all of that. Benchmarks consistently put it ahead of cout for string construction, often significantly. 🧠 Key insight: printf is unsafe because the format string and the arguments are disconnected, and the compiler can't match them. 𝒄𝒐𝒖𝒕 is safe, but composing output is syntactic noise. 𝒔𝒕𝒅::𝒇𝒐𝒓𝒎𝒂𝒕 gives you the readability of one and the safety of the other, with better performance than both. Worth knowing: 𝒔𝒕𝒅::𝒇𝒐𝒓𝒎𝒂𝒕 returns a 𝒔𝒕𝒅::𝒔𝒕𝒓𝒊𝒏𝒈. Use 𝒔𝒕𝒅::𝒑𝒓𝒊𝒏𝒕 (C++23) to write directly to stdout without constructing one. Format specifiers still exist for precision and alignment {:.2𝒇}, {:>10}, but you only reach for them when you need them. · Custom types can opt in via a 𝒔𝒕𝒅::𝒇𝒐𝒓𝒎𝒂𝒕𝒕𝒆𝒓<𝑻> specialization of your types, your formatting rules. · Not on C++20 yet? The {𝒇𝒎𝒕} library is the identical open-source predecessor. Same API, drop-in ready. Write format strings that read like sentences. Not code that reads like noise. Day 12 of my C++ deep-dive series. Missed Day 11? Go check out the composition over inheritance breakdown. Still on printf or cout in your codebase? What's blocking the move to 𝒔𝒕𝒅::𝒇𝒐𝒓𝒎𝒂𝒕? 👇 #cpp #cplusplus #cpp20 #programming #softwareengineering
Baffour Kusi Frimpong’s Post
More Relevant Posts
-
Part 3 of Routing Back to C is up. A hash table in plain C with chaining, buckets .... and a lot more https://lnkd.in/dG-nvQFJ [Part 3] #C #Programming #GameDev #LLM #LearnInPublic
To view or add a comment, sign in
-
Your regex runs on every request. It also recompiles on every request - unless you do something about it. `Regex.IsMatch` handles the quick yes/no check. Named groups let you pull out values by name instead of counting parentheses like it's 1999. And `[GeneratedRegex]`, shipped in .NET 7, compiles your pattern straight to IL at build time - zero runtime overhead, and your profiler finally stops yelling at you. --- var match = Regex.Match(log, @"user=(?<email>[\w.]+@[\w.]+)\s+action=(?<action>\S+)"); Console.WriteLine(match.Groups["email"].Value); // no index guessing --- Microsoft made regex fast by default. Only took until 2022. Try it yourself (no setup required): https://lnkd.in/eg68aQiZ #dotnet #csharp #programming #regex
To view or add a comment, sign in
-
-
Are arr and &arr the same thing in C? 🤔 int arr[10]; They both point to the same physical starting memory address! But they are fundamentally different from the compiler. Let’s look at the math if our array starts at address 1000: 📍 arr (Pointer to the 1st element) ->Evaluates to address 1000 ->Adding 1 moves forward by 1 integer (4 bytes) ->arr + 1 = 1004 📦 &arr (Pointer to the entire array) ->Evaluates to address 1000 ->Adding 1 moves forward by the whole array size (40 bytes) ->&arr + 1 = 1040 (the slot just after the array) 💥 The "No Size of" Length Trick: Size of Array without using the sizeof() function. Because &arr + 1 points to the address just after the array (1040), subtracting the starting address (1000) from it yields the exact number of elements! int length = *(&arr + 1) - arr; // gives the result of 10 ⚠️ Note: Dereferencing a one-past-the-end pointer is undefined behavior in standard C — this trick is purely for understanding pointer arithmetic, not for production code. Why dereferencing *(&arr + 1) : *(&arr + 1) dereferences the array pointer, and the result naturally decays from int[10] to int * — so the subtraction gives you element count, not bytes. When you subtract two pointers in C, the compiler looks at their data type and says, "These are pointers to integers. The programmer wants to know how many integers fit between these two addresses, not the raw number of bytes." It automatically applies the scale division without requiring you to use the sizeof() operator in your code. Summary: They share the same address, but they have completely different "step sizes" in pointer arithmetic. #CProgramming #Pointers #CodingTips #SoftwareDevelopment #EmbeddedC #EmbeddedSystems
To view or add a comment, sign in
-
C++ functions are simple, let me explain: There's two type of functions: free/normal functions and class functions. A class function, also referred to as a "method", applies to an instance of the class (an object). Under the hood it's just a normal function taking a pointer to the instance as argument. Except when the function is static, then it does not apply to an instance. There are special functions in classes, like the default, move and assignment constructors. There are also operators, which means for example you can write classA + classB and implement custom logic for what should happen. Functions can be inline or externally defined. Class functions that are defined when declared are implicitely inline. Class functions can be marked as const, which can be called on const objects. Functions can also be constexpr or consteval but that's all about moving computation to compile time. You're still with me? When defining the function call operator() for a class, you can treat the class as a function. This is useful when you want to pass it as a function into another function. Lambdas are syntactic sugar around function objects. std::function is not a function. It's an object, wrapping anything callable, including function pointers, or function objects. A lambda should not be confusing with std::function but you can put a lamba inside an std::function. That's all. Oh no, I forgot to mention virtual functions, template functions, throwing vs non throwing functions, deleted functions, user generated functions vs compiler generated functions, non returning functions, coroutines, function contracts... 🤯 Simple, right? 😉 Join my newsletter: https://lnkd.in/eqzAYgs6
To view or add a comment, sign in
-
🚀 Day 578 of #750DaysOfCode 🚀 🔍 Problem Solved: Maximum Path Score in a Grid Today’s problem was a solid mix of Dynamic Programming + Constraint Handling (Knapsack-style) 🧠🔥 💡 Key Insight: Each cell gives: Score → maximize Cost → must stay ≤ k 👉 This becomes: “Find max score path with cost constraint” 🧠 Approach (Optimized DP): Instead of full 3D DP, we optimize using: 👉 prev[j][c] = max score at column j with cost c For each cell: Move from top (previous row) Move from left (current row) We: Add score Add cost (only if value > 0) Track best result 📈 Complexity: Time: O(m × n × k) Space: O(n × k) ✨ Takeaway: 👉 This is a grid + DP + budget constraint problem 👉 Optimize space by using rolling arrays 👉 Think of cost as a dimension like knapsack Harder than it looks — but very rewarding once it clicks 💪 #LeetCode #DSA #Java #DynamicProgramming #CodingJourney #ProblemSolving #Algorithms #LearningEveryday #Knapsack
To view or add a comment, sign in
-
-
#Day-5 of 30 Days/30 Posts challenge. 👉 upgrading the C++ advanced concepts.... 💢 Understanding the nuances of polymorphism is what separates a good C++ developer from a great one. While both Function Overloading and Function Overriding allow for multiple behaviors under the same function name, they serve entirely different purposes in system design. 🔹 Here is a breakdown of how to distinguish and master these two pillars of C++. 1. Function Overloading (Static Polymorphism) Overloading allows you to define multiple functions with the same name in the same scope, provided they have different signatures (parameters). It’s about flexibility in inputs. ▫️ When it happens: Compile-time. The Rule: Functions must differ by the number or type of arguments. Example: Having multiple log() functions—one for std::string and another for int error codes. 2. Function Overriding (Dynamic Polymorphism) Overriding occurs when a derived class provides a specific implementation for a virtual function declared in a base class. It’s about flexibility in behavior. ▫️ When it happens: Runtime. The Rule: The function signature must be identical to the base class version. The Modern Standard: Since C++11, always use the override keyword. It tells the compiler to double-check that you are actually overriding a base function, preventing silent errors if the signatures drift. Key Comparison : Feature FunctionOverloading FunctionOverriding ▫️ Binding Static (Early Binding) Dynamic (Late Binding) ▫️ Scope Same class or scope Base and Derived classes ▫️ Inheritance Not required Mandatory ▫️ Signature Must be different Must be identical Pro-Tip for Scalable Architecture: Overriding is essential for the Open/Closed Principle. By defining a common interface in a base class and overriding it in specialized versions, you can add new functionality to your system without modifying existing code that relies on the base pointer. In high-performance or financial systems, remember that overriding comes with the small overhead of a virtual table (vtable) lookup. If performance is extremely critical and the types are known at compile-time, consider templates (CRTP) as a static alternative to overriding. Which one do you find most critical in your current projects? Let's discuss in the comments! 👇 #CPlusPlus #SoftwareEngineering #ProgrammingTips #OOP #ModernCPP #CodingStandards #TechLeadership
To view or add a comment, sign in
-
-
The most dangerous phrase in software is: "But it works on my machine." ⚠️ I decided to eliminate that phrase entirely for my latest project. This video captures the "black box" transformation—using the Nuitka compiler to translate thousands of lines of Python into optimized C code. It’s a tense few minutes watching the machine stitch together ezdxf, win32com, and Tkinter into a single, indestructible executable. The Mystery: Why go through the trouble of a C-level compilation instead of just running a script? Because when a tool hits the production floor, it needs to be more than just "code." It needs to be a professional-grade solution for engineering efficiency. The goal was to take a complex environment and vanish it—leaving behind nothing but a high-performance, standalone tool. The Result: The "Successfully created" message at the end isn't just a build log. It’s the birth of LCPL_Grey_Scaler.exe (v1.1). No Python installation needed. No dependency errors. Just pure, compiled speed. 🚀 #Python #SoftwareEngineering #Automation #CAD #Nuitka #Innovation #CodingLife #Engineering #Deployment
To view or add a comment, sign in
-
🔥 DSA Challenge – Day 128/360 🚀 📌 Topic: Recursion 🧩 Problem: Letter Combinations of a Phone Number 💡 Problem Statement: Given a string of digits (2–9), return all possible letter combinations that the number could represent based on the classic phone keypad mapping. 🔍 Example: Input: "23" Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"] 💡 Approach: Backtracking (Recursion) We treat this like a decision tree: Each digit maps to multiple characters For every digit, we try all possible letters Build combinations step-by-step using recursion 👉 Key Idea: Choose → Explore → Backtrack Use StringBuilder for efficient string manipulation ⚙️ Steps: Create a mapping for digits → letters Start recursion from index 0 For each digit: Loop through its mapped letters Add letter to current string Move to next digit Backtrack (remove last character) 🚀 Code Highlights: ✔️ Base case: when index reaches end → add combination ✔️ Efficient backtracking using StringBuilder ✔️ Avoids extra space by modifying same string ⏱️ Time Complexity: O(4^N) 📦 Space Complexity: O(N) (recursion stack) Master this → You master recursion 🔥 #DSA #Java #Backtracking #CodingInterview #LeetCode #128DaysOfCode #Programming #Tech #ProblemSolving
To view or add a comment, sign in
-
-
You ever stare at a regex match and try to figure out what 'group[3]' actually means? Yeah, same. Named capture groups let you label parts of your pattern so 'match.Groups["date"]' actually tells you something. Pair that with 'Regex.IsMatch' for quick yes/no checks, and you suddenly feel like you know what you are doing. Introduced back in .NET 1.1, regex named groups have been quietly saving developers from their own cryptic patterns for over two decades. .NET 7 went further with source-generated regex - compile-time validation so you break at build, not at 2am. It is like spell-check, but for your paranoia. --- var pattern = @"(?<date>\d{4}-\d{2}-\d{2}) (?<level>\w+)"; var match = Regex.Match(logLine, pattern); Console.WriteLine(match.Groups["date"].Value); --- Run it, break it, learn it: https://lnkd.in/e-_w4N-f #dotnet #csharp #programming #regex
To view or add a comment, sign in
-
-
🐱💻 DAY 64. C# Null Safety Attributes: [NotNullWhen] & [MemberNotNull] ❓ Why do we use [NotNullWhen] and [MemberNotNull] in C#? 👉Because the compiler doesn’t always understand our runtime logic around null values, especially in complex code. 🐱🐾 [NotNullWhen(true)] Used to tell the compiler: “If this method returns true, the output value is NOT null.” 🐾Example: using System.Diagnostics.CodeAnalysis; public static bool TryGetValue(string? input, [NotNullWhen(true)] out string? result) { result = input; if (!string.IsNullOrWhiteSpace(input)) return true; result = null; return false; } if (TryGetValue("ERP", out var value)) { Console.WriteLine(value.Length); // No warning ❗ } ✔ Compiler now understands the null guarantee inside the if block. 🐱🐾 [MemberNotNull] Used when a method guarantees that certain class members are initialized. “After this method runs, these fields are NOT null.” 🐾 Example: using System.Diagnostics.CodeAnalysis; public class Repository { private string? _connectionString; [MemberNotNull(nameof(_connectionString))] public void Initialize(string connectionString) { _connectionString = connectionString; } public void Print() { Initialize("ConnectionStringExample"); Console.WriteLine(_connectionString.Length); // No warning after Initialize() } } 🐱🐾 Why this matters ✔ Reduces unnecessary null warnings ✔ Avoids overusing ! (null-forgiving operator)
To view or add a comment, sign in
-
More from this author
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development
Internationalization would like to have a word... Often messages in other languages will require a reordering of the substitutions. Both printf and this new way will continue to fail in a multi-lingual program. Still, swing and a miss as far as I'm concerned.