summaryrefslogtreecommitdiff
path: root/gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.html
blob: 6071ea5149b43cff7b43c058f3477a4f0098425d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Object oriented programming with ANSI C</title>
<link rel="shortcut icon" type="image/gif" href="/favicon.ico" />
<link rel="stylesheet" href="../style.css" />
<link rel="stylesheet" href="style-override.css" />
</head>
<body class="rfx-boot">
<div class="rfx-overlay-grid"></div>
<div class="rfx-overlay-scanlines"></div>
<div id="rfx-stars"></div>
<div class="rfx-vignette"></div>
<p class="header">
<a href="https://foo.zone">Home</a> | <a href="https://codeberg.org/snonux/foo.zone/src/branch/content-md/gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.md">Markdown</a> | <a href="gemini://foo.zone/gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi">Gemini</a>
</p>
<h1 style='display: inline' id='object-oriented-programming-with-ansi-c'>Object oriented programming with ANSI C</h1><br />
<br />
<span class='quote'>Published at 2016-11-20T22:10:57+00:00; Updated at 2022-01-29</span><br />
<br />
<pre>
  ___   ___  ____        ____ 
 / _ \ / _ \|  _ \      / ___|
| | | | | | | |_) |____| |    
| |_| | |_| |  __/_____| |___ 
 \___/ \___/|_|         \____|
                              
</pre>
<br />
<span>You can do a little of object-oriented programming in the C Programming Language. However, that is, in my humble opinion, limited. It&#39;s easier to use a different programming language than C for OOP. But still it&#39;s an interesting exercise to try using C for this.</span><br />
<br />
<h2 style='display: inline' id='function-pointers'>Function pointers</h2><br />
<br />
<span>Let&#39;s have a look at the following sample program. All you have to do is to add a function pointer such as "calculate" to the definition of struct "something_s". Later, during the struct initialization, assign a function address to that function pointer:</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><font color="#ababab">#include</font><font color="#ff0000"> </font><font color="#bb00ff">&lt;stdio.h&gt;</font>

<b><font color="#ffffff">typedef</font></b><font color="#ff0000"> </font><b><font color="#ffffff">struct</font></b><font color="#ff0000"> </font><font color="#F3E651">{</font>
<font color="#ff0000">    </font><b><font color="#F35E1E">double</font></b><font color="#ff0000"> </font><font color="#F3E651">(*</font><font color="#ff0000">calculate</font><font color="#F3E651">)(</font><b><font color="#ffffff">const</font></b><font color="#ff0000"> </font><b><font color="#F35E1E">double</font></b><font color="#F3E651">,</font><font color="#ff0000"> </font><b><font color="#ffffff">const</font></b><font color="#ff0000"> </font><b><font color="#F35E1E">double</font></b><font color="#F3E651">);</font>
<font color="#ff0000">    </font><b><font color="#F35E1E">char</font></b><font color="#ff0000"> </font><font color="#F3E651">*</font><font color="#ff0000">name</font><font color="#F3E651">;</font>
<font color="#F3E651">}</font><font color="#ff0000"> something_s</font><font color="#F3E651">;</font>

<b><font color="#F35E1E">double</font></b><font color="#ff0000"> </font><font color="#7bc710">multiplication</font><font color="#F3E651">(</font><b><font color="#ffffff">const</font></b><font color="#ff0000"> </font><b><font color="#F35E1E">double</font></b><font color="#ff0000"> a</font><font color="#F3E651">,</font><font color="#ff0000"> </font><b><font color="#ffffff">const</font></b><font color="#ff0000"> </font><b><font color="#F35E1E">double</font></b><font color="#ff0000"> b</font><font color="#F3E651">)</font><font color="#ff0000"> </font><font color="#F3E651">{</font>
<font color="#ff0000">    </font><b><font color="#ffffff">return</font></b><font color="#ff0000"> a </font><font color="#F3E651">*</font><font color="#ff0000"> b</font><font color="#F3E651">;</font>
<font color="#F3E651">}</font>

<b><font color="#F35E1E">double</font></b><font color="#ff0000"> </font><font color="#7bc710">division</font><font color="#F3E651">(</font><b><font color="#ffffff">const</font></b><font color="#ff0000"> </font><b><font color="#F35E1E">double</font></b><font color="#ff0000"> a</font><font color="#F3E651">,</font><font color="#ff0000"> </font><b><font color="#ffffff">const</font></b><font color="#ff0000"> </font><b><font color="#F35E1E">double</font></b><font color="#ff0000"> b</font><font color="#F3E651">)</font><font color="#ff0000"> </font><font color="#F3E651">{</font>
<font color="#ff0000">    </font><b><font color="#ffffff">return</font></b><font color="#ff0000"> a </font><font color="#F3E651">/</font><font color="#ff0000"> b</font><font color="#F3E651">;</font>
<font color="#F3E651">}</font>

<b><font color="#F35E1E">int</font></b><font color="#ff0000"> </font><font color="#7bc710">main</font><font color="#F3E651">(</font><b><font color="#F35E1E">void</font></b><font color="#F3E651">)</font><font color="#ff0000"> </font><font color="#F3E651">{</font>
<font color="#ff0000">    </font><font color="#ff0000">something_s</font><font color="#ff0000"> mult </font><font color="#F3E651">=</font><font color="#ff0000"> </font><font color="#F3E651">(</font><font color="#ff0000">something_s</font><font color="#F3E651">)</font><font color="#ff0000"> </font><font color="#F3E651">{</font>
<font color="#ff0000">        </font><font color="#F3E651">.</font><font color="#ff0000">calculate </font><font color="#F3E651">=</font><font color="#ff0000"> multiplication</font><font color="#F3E651">,</font>
<font color="#ff0000">        </font><font color="#F3E651">.</font><font color="#ff0000">name </font><font color="#F3E651">=</font><font color="#ff0000"> </font><font color="#bb00ff">"Multiplication"</font>
<font color="#ff0000">    </font><font color="#F3E651">}</font><font color="#F3E651">;</font>

<font color="#ff0000">    </font><font color="#ff0000">something_s</font><font color="#ff0000"> div </font><font color="#F3E651">=</font><font color="#ff0000"> </font><font color="#F3E651">(</font><font color="#ff0000">something_s</font><font color="#F3E651">)</font><font color="#ff0000"> </font><font color="#F3E651">{</font>
<font color="#ff0000">        </font><font color="#F3E651">.</font><font color="#ff0000">calculate </font><font color="#F3E651">=</font><font color="#ff0000"> division</font><font color="#F3E651">,</font>
<font color="#ff0000">        </font><font color="#F3E651">.</font><font color="#ff0000">name </font><font color="#F3E651">=</font><font color="#ff0000"> </font><font color="#bb00ff">"Division"</font>
<font color="#ff0000">    </font><font color="#F3E651">}</font><font color="#F3E651">;</font>

<font color="#ff0000">    </font><b><font color="#ffffff">const</font></b><font color="#ff0000"> </font><b><font color="#F35E1E">double</font></b><font color="#ff0000"> a </font><font color="#F3E651">=</font><font color="#ff0000"> </font><font color="#bb00ff">3</font><font color="#F3E651">,</font><font color="#ff0000"> b </font><font color="#F3E651">=</font><font color="#ff0000"> </font><font color="#bb00ff">2</font><font color="#F3E651">;</font>

<font color="#ff0000">    </font><font color="#7bc710">printf</font><font color="#F3E651">(</font><font color="#bb00ff">"%s(%f, %f) =&gt; %f</font><font color="#ffffff">\n</font><font color="#bb00ff">"</font><font color="#F3E651">,</font><font color="#ff0000"> mult</font><font color="#F3E651">.</font><font color="#ff0000">name</font><font color="#F3E651">,</font><font color="#ff0000"> a</font><font color="#F3E651">,</font><font color="#ff0000"> b</font><font color="#F3E651">,</font><font color="#ff0000"> mult</font><font color="#F3E651">.</font><font color="#7bc710">calculate</font><font color="#F3E651">(</font><font color="#ff0000">a</font><font color="#F3E651">,</font><font color="#ff0000">b</font><font color="#F3E651">));</font>
<font color="#ff0000">    </font><font color="#7bc710">printf</font><font color="#F3E651">(</font><font color="#bb00ff">"%s(%f, %f) =&gt; %f</font><font color="#ffffff">\n</font><font color="#bb00ff">"</font><font color="#F3E651">,</font><font color="#ff0000"> div</font><font color="#F3E651">.</font><font color="#ff0000">name</font><font color="#F3E651">,</font><font color="#ff0000"> a</font><font color="#F3E651">,</font><font color="#ff0000"> b</font><font color="#F3E651">,</font><font color="#ff0000"> div</font><font color="#F3E651">.</font><font color="#7bc710">calculate</font><font color="#F3E651">(</font><font color="#ff0000">a</font><font color="#F3E651">,</font><font color="#ff0000">b</font><font color="#F3E651">));</font>
<font color="#F3E651">}</font>
</pre>
<br />
<span>As you can see, you can call the function (pointed by the function pointer) with the same syntax as in C++ or Java:</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><font color="#7bc710">printf</font><font color="#F3E651">(</font><font color="#bb00ff">"%s(%f, %f) =&gt; %f</font><font color="#ffffff">\n</font><font color="#bb00ff">"</font><font color="#F3E651">,</font><font color="#ff0000"> mult</font><font color="#F3E651">.</font><font color="#ff0000">name</font><font color="#F3E651">,</font><font color="#ff0000"> a</font><font color="#F3E651">,</font><font color="#ff0000"> b</font><font color="#F3E651">,</font><font color="#ff0000"> mult</font><font color="#F3E651">.</font><font color="#7bc710">calculate</font><font color="#F3E651">(</font><font color="#ff0000">a</font><font color="#F3E651">,</font><font color="#ff0000">b</font><font color="#F3E651">));</font>
<font color="#7bc710">printf</font><font color="#F3E651">(</font><font color="#bb00ff">"%s(%f, %f) =&gt; %f</font><font color="#ffffff">\n</font><font color="#bb00ff">"</font><font color="#F3E651">,</font><font color="#ff0000"> div</font><font color="#F3E651">.</font><font color="#ff0000">name</font><font color="#F3E651">,</font><font color="#ff0000"> a</font><font color="#F3E651">,</font><font color="#ff0000"> b</font><font color="#F3E651">,</font><font color="#ff0000"> div</font><font color="#F3E651">.</font><font color="#7bc710">calculate</font><font color="#F3E651">(</font><font color="#ff0000">a</font><font color="#F3E651">,</font><font color="#ff0000">b</font><font color="#F3E651">));</font>
</pre>
<br />
<span>However, that&#39;s just syntactic sugar for:</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><font color="#7bc710">printf</font><font color="#F3E651">(</font><font color="#bb00ff">"%s(%f, %f) =&gt; %f</font><font color="#ffffff">\n</font><font color="#bb00ff">"</font><font color="#F3E651">,</font><font color="#ff0000"> mult</font><font color="#F3E651">.</font><font color="#ff0000">name</font><font color="#F3E651">,</font><font color="#ff0000"> a</font><font color="#F3E651">,</font><font color="#ff0000"> b</font><font color="#F3E651">,</font><font color="#ff0000"> </font><font color="#F3E651">(*</font><font color="#ff0000">mult</font><font color="#F3E651">.</font><font color="#ff0000">calculate</font><font color="#F3E651">)(</font><font color="#ff0000">a</font><font color="#F3E651">,</font><font color="#ff0000">b</font><font color="#F3E651">));</font>
<font color="#7bc710">printf</font><font color="#F3E651">(</font><font color="#bb00ff">"%s(%f, %f) =&gt; %f</font><font color="#ffffff">\n</font><font color="#bb00ff">"</font><font color="#F3E651">,</font><font color="#ff0000"> div</font><font color="#F3E651">.</font><font color="#ff0000">name</font><font color="#F3E651">,</font><font color="#ff0000"> a</font><font color="#F3E651">,</font><font color="#ff0000"> b</font><font color="#F3E651">,</font><font color="#ff0000"> </font><font color="#F3E651">(*</font><font color="#ff0000">div</font><font color="#F3E651">.</font><font color="#ff0000">calculate</font><font color="#F3E651">)(</font><font color="#ff0000">a</font><font color="#F3E651">,</font><font color="#ff0000">b</font><font color="#F3E651">));</font>
</pre>
<br />
<span>Output:</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><font color="#ff0000">pbuetow </font><font color="#F3E651">~</font><font color="#ff0000">/git/blog/source </font><font color="#F3E651">[</font><font color="#bb00ff">38268</font><font color="#F3E651">]%</font><font color="#ff0000"> gcc oop-c-example</font><font color="#F3E651">.</font><font color="#ff0000">c -o oop-c-example</font>
<font color="#ff0000">pbuetow </font><font color="#F3E651">~</font><font color="#ff0000">/git/blog/source </font><font color="#F3E651">[</font><font color="#bb00ff">38269</font><font color="#F3E651">]%</font><font color="#ff0000"> </font><font color="#F3E651">.</font><font color="#ff0000">/oop-c-example</font>
<font color="#ff0000">Multiplication</font><font color="#F3E651">(</font><font color="#bb00ff">3.000000</font><font color="#F3E651">,</font><font color="#ff0000"> </font><font color="#bb00ff">2.000000</font><font color="#F3E651">)</font><font color="#ff0000"> </font><font color="#F3E651">=&gt;</font><font color="#ff0000"> </font><font color="#bb00ff">6.000000</font>
<font color="#ff0000">Division</font><font color="#F3E651">(</font><font color="#bb00ff">3.000000</font><font color="#F3E651">,</font><font color="#ff0000"> </font><font color="#bb00ff">2.000000</font><font color="#F3E651">)</font><font color="#ff0000"> </font><font color="#F3E651">=&gt;</font><font color="#ff0000"> </font><font color="#bb00ff">1.500000</font>
</pre>
<br />
<span>Not complicated at all, but nice to know and helps to make the code easier to read!</span><br />
<br />
<h2 style='display: inline' id='that-s-not-oop-though'>That&#39;s not OOP, though</h2><br />
<br />
<span>However, that&#39;s not really how it works in object-oriented languages such as Java and C++. The method call in this example is not a method call as "mult" and "div" in this example are not "message receivers". I mean that the functions can not access the state of the "mult" and "div" struct objects. In C, you would need to do something like this instead if you wanted to access the state of "mult" from within the calculate function, you would have to pass it as an argument:</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><font color="#ff0000">mult</font><font color="#F3E651">.</font><font color="#7bc710">calculate</font><font color="#F3E651">(</font><font color="#ff0000">mult</font><font color="#F3E651">,</font><font color="#ff0000">a</font><font color="#F3E651">,</font><font color="#ff0000">b</font><font color="#F3E651">));</font>
</pre>
<br />
<h2 style='display: inline' id='real-object-oriented-programming-with-c'>Real object oriented programming with C</h2><br />
<br />
<span>If you want to take it further, hit "Object-Oriented Programming with ANSI-C" into your favourite internet search engine or follow the link below. It goes as far as writing a C preprocessor in AWK, which takes some object-oriented pseudo-C and transforms it to plain C so that the C compiler can compile it to machine code. This is similar to how the C++ language had its origins.</span><br />
<br />
<a class='textlink' href='https://www.cs.rit.edu/~ats/books/ooc.pdf'>https://www.cs.rit.edu/~ats/books/ooc.pdf</a><br />
<br />
<h2 style='display: inline' id='oop-design-patterns-in-the-linux-kernel'>OOP design patterns in the Linux Kernel</h2><br />
<br />
<span>Big C software projects, like Linux, also follow some OOP techniques:</span><br />
<br />
<a class='textlink' href='https://lwn.net/Articles/444910/'>https://lwn.net/Articles/444910/</a><br />
<br />
<span>C is a very old programming language with it&#39;s quirks. This might be one of the reasons why Linux will also let Rust code in.</span><br />
<br />
<span>E-Mail your comments to <span class='inlinecode'>paul@nospam.buetow.org</span> :-)</span><br />
<br />
<a class='textlink' href='../'>Back to the main site</a><br />
<p class="footer">
    Generated with <a href="https://codeberg.org/snonux/gemtexter">Gemtexter 3.0.1-develop</a> |
    served by <a href="https://www.OpenBSD.org">OpenBSD</a>/<a href="https://man.openbsd.org/relayd.8">relayd(8)</a>+<a href="https://man.openbsd.org/httpd.8">httpd(8)</a> |
    <a href="https://foo.zone/site-mirrors.html">Site Mirrors</a>
    <br />
    Webring: <a href="https://shring.sh/foo.zone/previous">previous</a> | <a href="https://shring.sh">shring</a> | <a href="https://shring.sh/foo.zone/next">next</a>
</p>
<script type="text/javascript" src="../retrofuturistic.js"></script>
</body>
</html>