Skip to content

Commit c47e1b0

Browse files
committed
Align cpp demos with docs 41-50 (extern through functions)
Each cpp mirrors only what its doc covers, with short labeled demos. - src/extern/variable/{main.cpp,global.h,global.cpp}: two-TU demo of extern variable across translation units (global.h declares, global.cpp defines, main.cpp reads + writes). - src/extern/function/{main.cpp,foo.c,foo.h}: extern "C" linkage of a C function called from C++. foo.h guards `extern "C"` under __cplusplus. - src/filesystem.cpp: self-contained /tmp/fs_demo walkthrough — path decomposition, create_directory/_directories, exists/is_*, file_size, copy_file/copy, current_path, absolute/relative, last_write_time, directory_iterator/recursive_directory_iterator, remove/remove_all. - src/fork.cpp: parent/child branching via fork() return value, getpid(), global vs stack copy-on-write, parent waits for child to avoid zombie. - Create src/format.cpp: {} substitution, width/alignment/fill, precision, base/sign/zero-padding, positional args, chrono, custom std::formatter, format_to, vformat. std::print/println gated on __cpp_lib_print. - src/forward.cpp: minimal Resource with printable copy/move ctors; lvalue and rvalue f() overloads; wrap() loses category, wrap_forward() preserves it via std::forward<T>. - Create src/functions.cpp: index pointing at function_pointer / function / bind / lambda / callbacks / inline_functions for shared topics, plus tiny unique demos (constexpr, noexcept, return-by-value, ref-to-member, const-ref return). - CMakeLists: add extern_variable / extern_function / filesystem / format / functions executables; project switched to LANGUAGES CXX C for foo.c. - Skipped fPIE_and_fPIC.md, generating_and_debugging_dump_file.md, get_the_release_version_github.md, getting_version_from_git_in_CMake.md (all meta-docs about tools/build flags with no companion cpp).
1 parent f58a74b commit c47e1b0

12 files changed

Lines changed: 405 additions & 278 deletions

File tree

CMakeLists.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.20)
2-
project(cpp_tutorials LANGUAGES CXX)
2+
project(cpp_tutorials LANGUAGES CXX C)
33

44
# This project uses per-config output directories, so it requires a
55
# multi-config generator. Ninja Multi-Config is the recommended choice.
@@ -62,6 +62,7 @@ endif()
6262
# ---------------------------------------------------------------------------
6363
add_executable(pointers src/pointers/pointers.cpp)
6464
add_executable(string src/string.cpp)
65+
add_executable(format src/format.cpp)
6566
add_executable(exception_handling src/exception_handling.cpp)
6667
add_executable(assert src/assert.cpp)
6768
add_executable(return_abort_exit src/return_abort_exit.cpp)
@@ -90,9 +91,11 @@ add_executable(iterator_loop src/iterator_loop.cpp)
9091
add_executable(function_pointer src/function_pointer.cpp)
9192
add_executable(bind src/bind.cpp)
9293
add_executable(function src/function.cpp)
94+
add_executable(functions src/functions.cpp)
9395
add_executable(lambda src/lambda.cpp)
9496
add_executable(unions src/unions.cpp)
9597
add_executable(basic_IO_operation_streams src/basic_IO_operation_filesystem_streams_reading_writing_files_formating_output_cin_cout_scanf_printf_gets_puts_getline.cpp)
98+
add_executable(filesystem src/filesystem.cpp)
9699
add_executable(const_constexpr_mutable src/const_constexpr_mutable.cpp)
97100
add_executable(literals src/literals.cpp)
98101
add_executable(ternary src/ternary.cpp)
@@ -162,6 +165,14 @@ add_executable(circular_dependency
162165
src/class/circular_dependency/classA.cpp
163166
src/class/circular_dependency/classB.cpp)
164167

168+
# extern: cross-TU global variable and extern "C" linkage to a C function.
169+
add_executable(extern_variable
170+
src/extern/variable/main.cpp
171+
src/extern/variable/global.cpp)
172+
add_executable(extern_function
173+
src/extern/function/main.cpp
174+
src/extern/function/foo.c)
175+
165176
# ---------------------------------------------------------------------------
166177
# Advanced C++ concepts / idioms
167178
# ---------------------------------------------------------------------------

src/extern/function/foo.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#include <stdio.h>
2+
13
#include "foo.h"
24

3-
void foo() { printf("foo here"); }
5+
// Defined in a .c file, compiled by the C compiler. Its symbol is plain
6+
// "foo", with no C++ name mangling.
7+
void foo(void) { printf("foo here (from C)\n"); }

src/extern/function/foo.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,15 @@
1-
void foo();
1+
#pragma once
2+
3+
// This header is shared between foo.c (C compiler) and main.cpp (C++ compiler).
4+
// When the C++ side includes it, we wrap the declarations in extern "C" so the
5+
// C++ compiler uses C-style (non-mangled) linkage and matches the symbol that
6+
// the C compiler produced for foo().
7+
#ifdef __cplusplus
8+
extern "C" {
9+
#endif
10+
11+
void foo(void);
12+
13+
#ifdef __cplusplus
14+
}
15+
#endif

src/extern/function/main.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1-
/*
2-
c++ mangle the name of functions so it will be able to overload function, while
3-
in "c", there is no overloading and function will have the same name in object
4-
file as what they had in their respective "c" file, so if we want to compile a
5-
"c" function in c++, we have to use it extern
1+
// Demo: calling a C function from C++.
2+
//
3+
// C++ mangles function names to support overloading; C does not. If we
4+
// declared foo() with normal C++ linkage, the linker would look for a
5+
// mangled symbol that the C compiler never produced. 'extern "C"' tells
6+
// the C++ compiler to use C linkage for these declarations so the names
7+
// match.
8+
//
9+
// foo.h already wraps its declarations in extern "C" when __cplusplus is
10+
// defined, so a plain #include is enough here.
11+
12+
#include <iostream>
613

7-
*/
8-
extern "C" {
914
#include "foo.h"
10-
}
1115

12-
int main() { foo(); }
16+
int main() {
17+
std::cout << "calling C function from C++:\n";
18+
foo();
19+
}

src/extern/variable/global.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// The single definition of g_value lives here. Other translation units
2+
// see it through the 'extern' declaration in global.h.
3+
int g_value = 10;

src/extern/variable/global.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#pragma once
2+
3+
// Declaration only: 'extern' tells the compiler that g_value is
4+
// defined in some other translation unit. No storage is reserved here.
5+
extern int g_value;

src/extern/variable/main.cpp

Lines changed: 13 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,18 @@
1-
/*
2-
* Extern.cpp
3-
*
4-
* Created on: Feb 22, 2012
5-
* Author: behnam
6-
*/
7-
#include <iostream>
8-
/*http://www.learncpp.com/cpp-tutorial/42-global-variables/
9-
* Variables declared outside of a block are called global variables. Global
10-
variables have program scope,
11-
* which means they can be accessed everywhere in the program, and they are only
12-
destroyed when the program ends.
13-
14-
int g_nX; // global variable
15-
16-
int main()
17-
{
18-
int nY; // local variable nY
19-
20-
// global vars can be seen everywhere in program
21-
// so we can change their values here
22-
g_nX = 5;
23-
} // nY is destroyed here
24-
25-
*/
26-
27-
/*
28-
In order to use a global variable that has been declared in another file, you
29-
have to use a forward declaration or a header file, along with the extern
30-
keyword.
31-
32-
33-
global.cpp:
34-
// declaration of g_nValue
35-
int g_nValue = 5;
36-
37-
main.cpp:
38-
// extern tells the compiler this variable is declared elsewhere
39-
extern int g_nValue;
40-
41-
int main()
42-
{
43-
g_nValue = 7;
44-
return 0;
45-
}
46-
47-
48-
_________________________________________________________________________________________________________________
49-
50-
Here is an example of using a header file extern:
51-
52-
global.cpp:
53-
54-
// declaration of g_nValue
55-
int g_nValue = 5;
56-
57-
global.h:
58-
#ifndef GLOBAL_H // header guards
59-
#define GLOBAL_H
60-
61-
// extern tells the compiler this variable is declared elsewhere
62-
extern int g_nValue;
63-
64-
#endif
65-
66-
main.cpp:
67-
#include "global.h"
68-
int main()
69-
{
70-
g_nValue = 7;
71-
return 0;
72-
}
1+
// Demo: using a global variable defined in another file via 'extern'.
2+
//
3+
// global.cpp : int g_value = 10; // definition
4+
// global.h : extern int g_value; // declaration
5+
// main.cpp : includes global.h and uses g_value
6+
//
7+
// The linker resolves the reference to the definition in global.cpp.
738

9+
#include <iostream>
7410

75-
*/
11+
#include "global.h"
7612

77-
using namespace std;
13+
int main() {
14+
std::cout << "initial g_value: " << g_value << '\n';
7815

79-
int Externmain()
80-
// in main()
81-
{
82-
return 0;
16+
g_value = 7;
17+
std::cout << "after write: " << g_value << '\n';
8318
}

0 commit comments

Comments
 (0)