<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>영혼을 불태우는 나의 열정.</title>
    <link>https://bunhere.tistory.com/</link>
    <description>뼈속까지 프로그래머라는 말을 들었다.
하지만, 난 그냥 샐러리맨이 되어가고 있고
이 곳은 몸부림의 흔적
(ryuan 골벵이 지메일)</description>
    <language>ko</language>
    <pubDate>Wed, 13 May 2026 07:50:15 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>소혼</managingEditor>
    <image>
      <title>영혼을 불태우는 나의 열정.</title>
      <url>https://t1.daumcdn.net/cfile/tistory/1659510D4A968CD257</url>
      <link>https://bunhere.tistory.com</link>
    </image>
    <item>
      <title>[책소개] &amp;quot;밑바닥부터 시작하는 웹브라우저&amp;quot; 소개</title>
      <link>https://bunhere.tistory.com/501</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDcZ3i/btsQGp1EEg1/Xume6luOSH8C8seYfKrggK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDcZ3i/btsQGp1EEg1/Xume6luOSH8C8seYfKrggK/img.png&quot; data-alt=&quot;방금 받은 따끈한 책&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDcZ3i/btsQGp1EEg1/Xume6luOSH8C8seYfKrggK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDcZ3i%2FbtsQGp1EEg1%2FXume6luOSH8C8seYfKrggK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;방금 받은 따끈한 책&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년에 가장 뿌듯한 일이 있다면 이 책을 번역한 일이라고 생각합니다.&lt;br /&gt;원래는 가제 &quot;크로미움 인터널&quot;에 관한 글을 적어보려고 생각했는데, 이 책 번역 기회가 닿아 &quot;글을 적는게 힘든 일이다&quot;를 배웠네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년 초까지 계속 수정을 거듭해 드디어 책이 손에 오니 감개 무량합니다.&lt;br /&gt;이 좋은 책을 정말 제가 번역한게 맞나 싶네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실상 현 직장에 이직한 이후 블로그를 방치했었는데, 이 책을 계기로 그동안 쌓았던 지식들을 정리해야겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 아주 쉬운 내용으로 시작해서 뒤로 가면 정말 프로그래밍 역량이 있어야 진행이 가능한 수준으로 난이도가 올라갑니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PROLOGUE. 브라우저와 웹&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹이 없던 시절 웹의 기원이 된 아이디어들부터 웹의 역사를 따라가며 브라우저의 등장과 발전, 브라우저 전쟁 이야기와 모던 브라우저까지의 이야기를 다루고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 이 책을 번역하기 전에는 몰랐던 이야기들이 많아서 너무 좋았습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qvz0e/btsQDwIgJQ8/DyWy5VssZkFXzMkAEyzWHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qvz0e/btsQDwIgJQ8/DyWy5VssZkFXzMkAEyzWHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qvz0e/btsQDwIgJQ8/DyWy5VssZkFXzMkAEyzWHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqvz0e%2FbtsQDwIgJQ8%2FDyWy5VssZkFXzMkAEyzWHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PART 1. 페이지 로딩&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹페이지를 읽어서 아주 간단하게 웹페이지의 콘텐츠를 화면에 그리는 텍스트만 있는 파이썬 프로그램을 작성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서도 폰트의 유래, 베이스라인, 어센트, 디센트에 대해서 배울 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹페이지를 파싱하는 기초적인 작업만으로도 브라우저를 만들어본 것같은 기분을 느낄 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PART 2. 문서 표시&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞장에서 만든 파이썬 프로그램을 본격적으로 개선해 브라우저의 뼈대를 만듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스트를 DOM 트리로 만들고, 기초적인 레이아웃의 개념을 배우실 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSS 스타일을 적용하고 버튼, 링크 처리등을 하는데 생각보다 어렵지 않게 따라하실 수 있을 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(여기까진 별 문제 없습니다)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PART 3. 애플리케이션 실행&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서부터는 조금 어려워지는데, 간단한 파이썬 서버를 만들어서 브라우저와 통신하게 할 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 자바스크립트를 바인딩하고 쿠키등의 데이터가 어떻게 처리되는지, 서버와 브라우저 코드를 같이 수정하면서 들여다 보는 것이 너무 좋았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안에 관련해서는 좀 더 정보가 많았으면 하는 바람이 있는데, 이 책의 범위를 넘어가는 부분이 있긴 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아쉽지만 이 책에서 다루는 정도만으로 웹의 최신 보안 기술들에 흥미를 가져볼 수 있을 것 같습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PART 4. 모던 브라우저 기능&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하.. 이때부터는 솔직히 어렵습니다. 여기를 직접 짜실 수 있는 분이면 훌륭한 개발자라고 인정해드릴 수 있겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책 예제가 모두 주어지지 않고 앞에서 작성한 코드에 수정을 할 것을 지시합니다. 알아서 다 수정하셔야 하고 안되면 디버깅을 열심히 하셔야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대신 모던 브라우저의 주요 기능들을 정말 다뤄봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멀티 프로세스는 다루지 않지만 멀티 스레드만으로도 얼마나 어려운이 느낄 수 있을 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애니메이션, 컴포지팅이 얼마나 어려운지도 아실 수 있을 것이고, 최적화를 위해 브라우저가 하는 더티비트 시스템에 대해 이해하실 수 있을 겁니다. (얼마나 어려운지요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 마지막 장, &quot;이전 결과 재사용&quot;은 정말 어려울 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 앞장까지만 구현해봐도 꽤 괜찮은 브라우저가 완성된걸 보실 수 있을 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PART 4 까지 보고, 예제도 직접 해보고 한다면 당분간 지루할 시간이 없을 파이썬 프로그램 하나를 만들어보시지 싶네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.yes24.com/Product/Goods/153499985&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.yes24.com/Product/Goods/153499985&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1758185583589&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;book&quot; data-og-title=&quot;밑바닥부터 시작하는 웹 브라우저 - 예스24&quot; data-og-description=&quot;웹 브라우저! 쌓고, 뜯고, 이해하라하나씩 이해하는 웹의 작동 원리크롬, 파이어폭스, 브레이브, 웨일 같은 웹 브라우저는 겉으로는 단순해 보이지만, 그 밑에는 무려 1천만 줄에 달하는 코드가 &quot; data-og-host=&quot;www.yes24.com&quot; data-og-source-url=&quot;https://www.yes24.com/Product/Goods/153499985&quot; data-og-url=&quot;https://www.yes24.com/product/goods/153499985&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dmcEbd/hyZJrpHmTU/jM84pp1M3csWHlKsqWKVUk/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200,https://scrap.kakaocdn.net/dn/blyWEo/hyZJmIIVtw/KJWg3NXndXL4L7WARlphRK/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200,https://scrap.kakaocdn.net/dn/dsJpqj/hyZJlQwXXf/PiZ1GjPY9jsKfsFlGZ2Ryk/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200&quot;&gt;&lt;a href=&quot;https://www.yes24.com/Product/Goods/153499985&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.yes24.com/Product/Goods/153499985&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dmcEbd/hyZJrpHmTU/jM84pp1M3csWHlKsqWKVUk/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200,https://scrap.kakaocdn.net/dn/blyWEo/hyZJmIIVtw/KJWg3NXndXL4L7WARlphRK/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200,https://scrap.kakaocdn.net/dn/dsJpqj/hyZJlQwXXf/PiZ1GjPY9jsKfsFlGZ2Ryk/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;밑바닥부터 시작하는 웹 브라우저 - 예스24&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;웹 브라우저! 쌓고, 뜯고, 이해하라하나씩 이해하는 웹의 작동 원리크롬, 파이어폭스, 브레이브, 웨일 같은 웹 브라우저는 겉으로는 단순해 보이지만, 그 밑에는 무려 1천만 줄에 달하는 코드가&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.yes24.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>browser engineering 관련</category>
      <category>밑바닥부터 시작하는 웹브라우저</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/501</guid>
      <comments>https://bunhere.tistory.com/501#entry501comment</comments>
      <pubDate>Thu, 18 Sep 2025 17:53:18 +0900</pubDate>
    </item>
    <item>
      <title>8장. 서버로 정보 보내기 추가 설명</title>
      <link>https://bunhere.tistory.com/500</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;8.2 위젯을 렌더링하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TextLayout은 self_rect가 필요 없었지만, InputLayout은 self_rect가 필요합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1756597678479&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class InputLayout
    def self_rect(self):
        return Rect(self.x, self.y,
            self.x + self.width, self.y + self.height)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>browser engineering 관련</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/500</guid>
      <comments>https://bunhere.tistory.com/500#entry500comment</comments>
      <pubDate>Sun, 31 Aug 2025 17:00:58 +0900</pubDate>
    </item>
    <item>
      <title>에러 상황들</title>
      <link>https://bunhere.tistory.com/499</link>
      <description>&lt;pre id=&quot;code_1756599227557&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;user@AL02296676 browserengineering-code % python3 browser.py http://localhost:8000/input.html
Traceback (most recent call last):
  File &quot;/Users/user/workspace/project/browserengineering-code/browser.py&quot;, line 1000, in &amp;lt;module&amp;gt;
    Browser().new_tab(URL(sys.argv[1]))
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File &quot;/Users/user/workspace/project/browserengineering-code/browser.py&quot;, line 987, in new_tab
    new_tab.load(url)
    ~~~~~~~~~~~~^^^^^
  File &quot;/Users/user/workspace/project/browserengineering-code/browser.py&quot;, line 773, in load
    self.document.layout()
    ~~~~~~~~~~~~~~~~~~~~^^
  File &quot;/Users/user/workspace/project/browserengineering-code/browser.py&quot;, line 660, in layout
    child.layout()
    ~~~~~~~~~~~~^^
  File &quot;/Users/user/workspace/project/browserengineering-code/browser.py&quot;, line 547, in layout
    child.layout()
    ~~~~~~~~~~~~^^
  File &quot;/Users/user/workspace/project/browserengineering-code/browser.py&quot;, line 547, in layout
    child.layout()
    ~~~~~~~~~~~~^^
  File &quot;/Users/user/workspace/project/browserengineering-code/browser.py&quot;, line 397, in layout
    max_ascent = max([word.font.metrics(&quot;ascent&quot;)
                      for word in self.children])
ValueError: max() iterable argument is empty&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LineLayout에서 이런 에러가 나면 빈 리스트에서 최대값을 찾으려고 하기 때문입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1756599354876&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;max_ascent = max(
    (word.font.metrics(&quot;ascent&quot;) for word in self.children),
    default=0
)

max_descent = max(
    (word.font.metrics(&quot;descent&quot;) for word in self.children),
    default=0
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와 같이 기본 값을 줘서 해결할 수 있습니다.&lt;/p&gt;</description>
      <category>browser engineering 관련</category>
      <category>책 추가 설명</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/499</guid>
      <comments>https://bunhere.tistory.com/499#entry499comment</comments>
      <pubDate>Sun, 31 Aug 2025 09:16:22 +0900</pubDate>
    </item>
    <item>
      <title>5장. 페이지 레이아웃의 추가 설명</title>
      <link>https://bunhere.tistory.com/498</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;5.1 레이아웃 트리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4장에서 만든 Layout 객체를 BlockLayout으로 바꾸고 DocumentLayout을 통해 BlockLayout들을 만들어가는 것이 목표입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5.1의 코드만 수정한 후 실행이 되려면 다음과 같은 코드가 추가로 필요합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1756535196048&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@@ -210,7 +216,7 @@ class Layout:
         self.size = 12
 
         self.line = []
-        self.recurse(tree)
+        self.recurse(self.node)
         self.flush()&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1756535212095&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@@ -286,7 +303,9 @@ class Browser:
     def load(self, url):
         body = url.request()
         self.nodes = HTMLParser(body).parse()
-        self.display_list = Layout(self.nodes).display_list
+        self.document = DocumentLayout(self.nodes)
+        self.document.layout()
+        self.display_list = self.document.children[0].display_list
         self.draw()
 
     def draw(self)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;self.display_list 를 변경하는 것은 5.5장까지 진도를 나가면 paint_tree를 통해 순회하는 방법이 등장합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1776&quot; data-origin-height=&quot;1442&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mfXkB/btsQdn5Evuu/BNnnDV003kXl1vLDyA8yK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mfXkB/btsQdn5Evuu/BNnnDV003kXl1vLDyA8yK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mfXkB/btsQdn5Evuu/BNnnDV003kXl1vLDyA8yK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmfXkB%2FbtsQdn5Evuu%2FBNnnDV003kXl1vLDyA8yK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1776&quot; height=&quot;1442&quot; data-origin-width=&quot;1776&quot; data-origin-height=&quot;1442&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>browser engineering 관련</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/498</guid>
      <comments>https://bunhere.tistory.com/498#entry498comment</comments>
      <pubDate>Sat, 30 Aug 2025 16:21:40 +0900</pubDate>
    </item>
    <item>
      <title>단순링크: 웹개발의 역사</title>
      <link>https://bunhere.tistory.com/497</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;책 내용과 비슷하지만, 조금 다른 부분들도 소개한 웹 개발의 역사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ppss.kr/archives/257673&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ppss.kr/archives/257673&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1755827847475&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;비전공자도 이해할 수 있는 웹 개발의 역사&quot; data-og-description=&quot;동영상이나, 음성 따위의 각종 멀티미디어를 이용하는 인터넷을 이르는 말. = 월드 와이드 웹. 국립국어원 표준국어대사전 &amp;nbsp; 시작하며 요즘 글이 뜸했습니다. 사실 뉴스레터 서비스가 유료로 전&quot; data-og-host=&quot;ppss.kr&quot; data-og-source-url=&quot;https://ppss.kr/archives/257673&quot; data-og-url=&quot;https://ppss.kr/archives/257673&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/d8Cz3z/hyZDbfIZbm/A6KNTe5ivRAUmM7Lwzd7rk/img.jpg?width=720&amp;amp;height=375&amp;amp;face=0_0_720_375&quot;&gt;&lt;a href=&quot;https://ppss.kr/archives/257673&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ppss.kr/archives/257673&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/d8Cz3z/hyZDbfIZbm/A6KNTe5ivRAUmM7Lwzd7rk/img.jpg?width=720&amp;amp;height=375&amp;amp;face=0_0_720_375');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;비전공자도 이해할 수 있는 웹 개발의 역사&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;동영상이나, 음성 따위의 각종 멀티미디어를 이용하는 인터넷을 이르는 말. = 월드 와이드 웹. 국립국어원 표준국어대사전 &amp;nbsp; 시작하며 요즘 글이 뜸했습니다. 사실 뉴스레터 서비스가 유료로 전&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ppss.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>browser engineering 관련</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/497</guid>
      <comments>https://bunhere.tistory.com/497#entry497comment</comments>
      <pubDate>Fri, 22 Aug 2025 10:58:01 +0900</pubDate>
    </item>
    <item>
      <title>DuckyPy 설치시 externally-managed-environment</title>
      <link>https://bunhere.tistory.com/496</link>
      <description>&lt;pre id=&quot;code_1752889430234&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;brew install pipx
pipx install dukpy​&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1752889096153&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;project % python3 -m pip install dukpy
error: externally-managed-environment

&amp;times; This environment is externally managed
╰─&amp;gt; To install Python packages system-wide, try brew install
    xyz, where xyz is the package you are trying to
    install.
    
    If you wish to install a Python library that isn't in Homebrew,
    use a virtual environment:
    
    python3 -m venv path/to/venv
    source path/to/venv/bin/activate
    python3 -m pip install xyz
    
    If you wish to install a Python application that isn't in Homebrew,
    it may be easiest to use 'pipx install xyz', which will manage a
    virtual environment for you. You can install pipx with
    
    brew install pipx
    
    You may restore the old behavior of pip by passing
    the '--break-system-packages' flag to pip, or by adding
    'break-system-packages = true' to your pip.conf file. The latter
    will permanently disable this error.
    
    If you disable this error, we STRONGLY recommend that you additionally
    pass the '--user' flag to pip, or set 'user = true' in your pip.conf
    file. Failure to do this can result in a broken Homebrew installation.
    
    Read more about this behavior here: &amp;lt;https://peps.python.org/pep-0668/&amp;gt;

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭔가 영어로 에러가 한 가득 나옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한마디로&amp;nbsp;말하면:&lt;br /&gt;&lt;br /&gt;&quot;시스템&amp;nbsp;전체에&amp;nbsp;직접&amp;nbsp;pip로&amp;nbsp;패키지를&amp;nbsp;설치하려고&amp;nbsp;했는데,&amp;nbsp;macOS의&amp;nbsp;Homebrew&amp;nbsp;Python에서는&amp;nbsp;이를&amp;nbsp;막고&amp;nbsp;있어요.&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결방법은 3가지중 첫번째를 추천합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 가상 환경 사용하기&lt;/p&gt;
&lt;pre id=&quot;code_1752889391370&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python3 -m venv venv
source venv/bin/activate
python3 -m pip install dukpy
...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. pipx로 설치하기&lt;/p&gt;
&lt;pre id=&quot;code_1752889440529&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;brew install pipx
pipx install dukpy&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 강제 설치하기&lt;/p&gt;
&lt;pre id=&quot;code_1752889449359&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python3 -m pip install --break-system-packages dukpy&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PEP668이 궁금하시면 아래 링크에서 보실 수 있습니다.&lt;br /&gt;&lt;a href=&quot;https://peps.python.org/pep-0668/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://peps.python.org/pep-0668/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1752889488911&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;PEP 668 &amp;ndash; Marking Python base environments as &amp;ldquo;externally managed&amp;rdquo; | peps.python.org&quot; data-og-description=&quot;A long-standing practical problem for Python users has been conflicts between OS package managers and Python-specific package management tools like pip. These conflicts include both Python-level API incompatibilities and conflicts over file ownership.&quot; data-og-host=&quot;peps.python.org&quot; data-og-source-url=&quot;https://peps.python.org/pep-0668/&quot; data-og-url=&quot;https://peps.python.org/pep-0668/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gdYdQ/hyZjCfkb9S/t5qs94n7JnvCJVESnDl5mk/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200&quot;&gt;&lt;a href=&quot;https://peps.python.org/pep-0668/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://peps.python.org/pep-0668/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gdYdQ/hyZjCfkb9S/t5qs94n7JnvCJVESnDl5mk/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PEP 668 &amp;ndash; Marking Python base environments as &amp;ldquo;externally managed&amp;rdquo; | peps.python.org&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A long-standing practical problem for Python users has been conflicts between OS package managers and Python-specific package management tools like pip. These conflicts include both Python-level API incompatibilities and conflicts over file ownership.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;peps.python.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>browser engineering 관련</category>
      <category>duckpy</category>
      <category>externally-managed-environment</category>
      <category>pep668</category>
      <category>Python</category>
      <category>python 에러</category>
      <category>맥에서 duckpy 설치시 오류</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/496</guid>
      <comments>https://bunhere.tistory.com/496#entry496comment</comments>
      <pubDate>Sat, 19 Jul 2025 10:45:42 +0900</pubDate>
    </item>
    <item>
      <title>[책] 인공지능, 주식분석 좀 부탁해</title>
      <link>https://bunhere.tistory.com/495</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;1214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSqoEx/btsPjjwGXF9/equusu1wKTxypx9145M5e1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSqoEx/btsPjjwGXF9/equusu1wKTxypx9145M5e1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSqoEx/btsPjjwGXF9/equusu1wKTxypx9145M5e1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSqoEx%2FbtsPjjwGXF9%2Fequusu1wKTxypx9145M5e1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;530&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;1214&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서평단에 신청해서 당첨?되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 제가 생각한것과는 많이 다르네요. 어떤걸 기대했던걸까 생각해보면 이 책이 최선이 아닌가 싶기도 합니다.&lt;br /&gt;프로그래밍과 주식 두가지 분야를 다루는 책인데, 둘 모두에 있어서 입문자의 관점에서 시작하는 책으로 생각됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1장은 파이썬의 기본 문법을 아주 간략하게 소개하고 있습니다.&lt;br /&gt;뒷부분에서 필요한 최소한의 파이썬 문법인듯 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2장은 실제 주식발굴을 위해 웹페이지에서 데이터를 긁어와 주식을 선별합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3장은 2장과 비슷한데, 차트를 파이썬으로 분석하고 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4장은 머신러닝을 이용해 기술적분석을 하는 파이썬 스크립트를 보여주고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 보면 한권으로 다룰 수 없는 방대한 양을 샘플 중심으로 다룬 책이란 생각이 듭니다.&lt;br /&gt;저에겐 1장은 아주 쉽고 2장도 쉬운편이지만, 뒤로 갈수록 시간을 들여 봐야겠다는 생각이 들었습니다.&lt;br /&gt;이걸로&amp;nbsp; 주식 투자의 고수가 되진 못하지만, 이걸 이해하고 나면 이렇게 접근하면 주식찾는데 도움을 받을 수 있겠구나 하는 인사이트를 얻었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서평을 쓰기엔 이 코드를 다 직접 다뤄보기엔 시간이 걸릴듯 합니다. 시간을 두고 따라 해볼 생각입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언젠가 이걸로 좋은 주식을 발굴해보면 좋겠다는 생각이 들었습니다.&lt;/p&gt;</description>
      <category>리뷰성 글들</category>
      <category>비제이퍼블릭</category>
      <category>인공지능</category>
      <category>주식분석</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/495</guid>
      <comments>https://bunhere.tistory.com/495#entry495comment</comments>
      <pubDate>Tue, 15 Jul 2025 23:37:35 +0900</pubDate>
    </item>
    <item>
      <title>브라우저 개발자 모임</title>
      <link>https://bunhere.tistory.com/493</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7yz3J/btsOr0RqfHl/zY8jyC3FXCdAsnW1W1wt30/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7yz3J/btsOr0RqfHl/zY8jyC3FXCdAsnW1W1wt30/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7yz3J/btsOr0RqfHl/zY8jyC3FXCdAsnW1W1wt30/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7yz3J%2FbtsOr0RqfHl%2FzY8jyC3FXCdAsnW1W1wt30%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;754&quot; height=&quot;542&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;713&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EwBaf/btsOrm14Qom/XBkE8zmXfNbNqHzcqNeU10/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EwBaf/btsOrm14Qom/XBkE8zmXfNbNqHzcqNeU10/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EwBaf/btsOrm14Qom/XBkE8zmXfNbNqHzcqNeU10/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEwBaf%2FbtsOrm14Qom%2FXBkE8zmXfNbNqHzcqNeU10%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1066&quot; height=&quot;713&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;713&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qB4kB/btsOrBdv1El/npfZoDGHZUBKH9IYmFkgTK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qB4kB/btsOrBdv1El/npfZoDGHZUBKH9IYmFkgTK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qB4kB/btsOrBdv1El/npfZoDGHZUBKH9IYmFkgTK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqB4kB%2FbtsOrBdv1El%2FnpfZoDGHZUBKH9IYmFkgTK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;960&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>browser engineering 관련</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/493</guid>
      <comments>https://bunhere.tistory.com/493#entry493comment</comments>
      <pubDate>Thu, 5 Jun 2025 21:23:57 +0900</pubDate>
    </item>
    <item>
      <title>[스크랩] 좋은 개발자의 특징</title>
      <link>https://bunhere.tistory.com/492</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://news.hada.io/topic?id=20244&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://news.hada.io/topic?id=20244&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1744590895519&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;내가 아는 최고의 개발자들이 공통적으로 가진 특성 | GeekNews&quot; data-og-description=&quot;저자는 다양한 개발자를 만나면서, 최고의 개발자들이 가진 공통된 특성에 대해 고민하게 됨이 글은 초보 개발자나 성장하고 싶은 사람들에게 영감을 주기 위해 작성된 관찰 기록임레퍼런스 문&quot; data-og-host=&quot;news.hada.io&quot; data-og-source-url=&quot;https://news.hada.io/topic?id=20244&quot; data-og-url=&quot;https://news.hada.io/topic?id=20244&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dgM3mz/hyYG5fX7K9/ke0yf8S7lwCrej4MPctkVk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/dPr78T/hyYB7NEk58/W4RzkeqA10EykjZ4n8IX1K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://news.hada.io/topic?id=20244&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://news.hada.io/topic?id=20244&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dgM3mz/hyYG5fX7K9/ke0yf8S7lwCrej4MPctkVk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/dPr78T/hyYB7NEk58/W4RzkeqA10EykjZ4n8IX1K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;내가 아는 최고의 개발자들이 공통적으로 가진 특성 | GeekNews&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;저자는 다양한 개발자를 만나면서, 최고의 개발자들이 가진 공통된 특성에 대해 고민하게 됨이 글은 초보 개발자나 성장하고 싶은 사람들에게 영감을 주기 위해 작성된 관찰 기록임레퍼런스 문&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;news.hada.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공감가는 좋은 글이라 스크랩해둡니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;저자는 다양한 개발자를 만나면서, 최고의 개발자들이 가진 공통된 특성에 대해 고민하게 됨&lt;/li&gt;
&lt;li&gt;이 글은 초보 개발자나 성장하고 싶은 사람들에게 영감을 주기 위해 작성된 관찰 기록임&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;레퍼런스 문서를 먼저 읽을 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Stack Overflow나 LLM을 먼저 찾기보다는 공식 문서를 먼저 읽는 습관을 들이는 것이 중요함&lt;/li&gt;
&lt;li&gt;Apache, Python, TOML 등의 공식 문서는 실제로 꽤 잘 작성되어 있음&lt;/li&gt;
&lt;li&gt;소스에서 직접 배우는 습관은 장기적으로 큰 도움이 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;도구를 깊이 이해할 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;도구를 &amp;lsquo;사용&amp;rsquo;할 줄 아는 것과, 그것을 &amp;lsquo;이해&amp;rsquo;하는 것은 다른 수준임&lt;/li&gt;
&lt;li&gt;도구를 잘 아는 사람은 설정 하나하나를 설명할 수 있음&lt;/li&gt;
&lt;li&gt;잘 이해하려면 도구의:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;역사 (왜 만들어졌는가)&lt;/li&gt;
&lt;li&gt;현재 (누가 관리하는가)&lt;/li&gt;
&lt;li&gt;한계 (언제 안 맞는가)&lt;/li&gt;
&lt;li&gt;생태계 (주변 도구, 라이브러리 등)&lt;br /&gt;를 모두 파악하고 있어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Kafka 등을 주력으로 쓴다면, Reddit에서 본 수준 이상으로 알고 있어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;에러 메시지를 꼼꼼히 읽을 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;에러 메시지를 곰곰이 들여다보면 힌트가 담겨 있음&lt;/li&gt;
&lt;li&gt;최고의 개발자는 적은 정보만 보고도 문제를 추론함&lt;/li&gt;
&lt;li&gt;문제의 80%는 에러 메시지만 잘 봐도 해결 가능함&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문제를 잘게 나눌 줄 알 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;막히는 건 누구나 겪는 일이고, 잘게 나눌 수 있어야 풀 수 있음&lt;/li&gt;
&lt;li&gt;경험이 많거나, 문제 해결 능력이 뛰어난 사람은 쉽게 나눔&lt;/li&gt;
&lt;li&gt;개발자의 핵심 업무는 결국 큰 문제를 작은 문제로 나누는 작업임&lt;/li&gt;
&lt;li&gt;단순한 문제들을 차근차근 풀면 전체 문제도 해결됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;두려움 없이 코드를 다룰 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최고의 개발자들은 코드 읽기를 두려워하지 않음&lt;/li&gt;
&lt;li&gt;&amp;ldquo;그건 내 영역이 아니야&amp;rdquo; 같은 말 없이 그냥 시도하고 배움&lt;/li&gt;
&lt;li&gt;처음 다룬 코드도 금세 팀 내 전문가가 되는 경우가 많음&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;항상 다른 사람을 도울 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;바쁜 와중에도 도와주는 개발자는 좋은 팀원이자 훌륭한 전문가임&lt;/li&gt;
&lt;li&gt;호기심과 협력적인 태도는 좋은 개발자의 필수 자질임&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;글을 쓸 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;뛰어난 개발자는 말도 잘하고, 생각을 글로 풀 줄 앎&lt;/li&gt;
&lt;li&gt;블로그, 발표, 오픈소스 활동 등으로 생각을 나눔&lt;/li&gt;
&lt;li&gt;글쓰기 능력은 사고의 구조와 직접적으로 연결되어 있음&lt;/li&gt;
&lt;li&gt;잘 쓰는 사람의 코드는 구조적이고, 명확하고, 때론 재치있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;배움을 멈추지 말 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;나이와 상관없이 계속 배우는 사람이 진짜 뛰어난 개발자임&lt;/li&gt;
&lt;li&gt;새로운 도구나 언어를 시도하는 것에 거리낌이 없음&lt;/li&gt;
&lt;li&gt;최신 기술을 맹목적으로 따르지 않고, 장단점을 스스로 분석할 줄 앎&lt;/li&gt;
&lt;li&gt;젊은 나이에도 고정관념에 빠지면 성장이 멈춤&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;지위에 연연하지 말 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;좋은 개발자는 직책과 상관없이 누구에게나 배움을 구함&lt;/li&gt;
&lt;li&gt;신입에게도 배울 게 있다는 태도를 가짐&lt;/li&gt;
&lt;li&gt;새로운 시각을 가진 사람들과의 대화에서 영감을 받음&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;명성을 쌓을 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실력도 중요하지만, 실력을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;알려지는 것&lt;/b&gt;도 중요함&lt;/li&gt;
&lt;li&gt;명성은 영향력을 넓히는 수단임&lt;/li&gt;
&lt;li&gt;다음과 같은 방법으로 명성을 쌓을 수 있음:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중요한 서비스를 직접 만들거나 배포함&lt;/li&gt;
&lt;li&gt;잘 알려진 도구를 개발함&lt;/li&gt;
&lt;li&gt;유명한 오픈소스에 기여함&lt;/li&gt;
&lt;li&gt;자주 인용되는 책을 씀&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;명성은 하루아침에 쌓이지 않으며, 꾸준한 노력과 시간이 필요함&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;인내심을 가질 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사람과 컴퓨터 모두에게 인내심이 필요함&lt;/li&gt;
&lt;li&gt;주변 사람은 바보가 아니라 정보가 부족한 것일 뿐임&lt;/li&gt;
&lt;li&gt;인내심 없으면 쉽게 불만이 쌓이고 협업이 어려워짐&lt;/li&gt;
&lt;li&gt;어려운 문제를 해결하려면 집중력과 끈기가 필요함&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;컴퓨터를 탓하지 말 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최고의 개발자는 절대 시스템이나 외부 요인을 탓하지 않음&lt;/li&gt;
&lt;li&gt;겉보기엔 무작위로 보이는 문제도 논리적인 이유가 있음&lt;/li&gt;
&lt;li&gt;원인을 찾기 위해 끝까지 파고드는 태도가 중요함&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;ldquo;모르겠습니다&amp;rdquo;를 말할 줄 알 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터뷰에서 일부러 &amp;ldquo;모르겠습니다&amp;rdquo;를 말하는 순간을 기다린 적 있음&lt;/li&gt;
&lt;li&gt;중요한 건 답이 아니라 태도임&lt;/li&gt;
&lt;li&gt;최고의 후보는 모른다고 인정하고, 추론을 시작함&lt;/li&gt;
&lt;li&gt;모른다고 인정하는 태도는 학습 가능성을 보여줌&lt;/li&gt;
&lt;li&gt;거짓말하거나 아는 척하는 사람은 팀에 부정적임&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;추측하지 말 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PEP 20의 철학처럼, 모호할 땐 절대 추측하지 말 것&lt;/li&gt;
&lt;li&gt;추측의 위험:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;틀리면 버그&lt;/li&gt;
&lt;li&gt;맞아도 잘못된 전제를 믿게 되어 나중에 문제 유발&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;확신이 없으면:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;질문하고&lt;/li&gt;
&lt;li&gt;문서 읽고&lt;/li&gt;
&lt;li&gt;디버깅 도구를 쓰고&lt;/li&gt;
&lt;li&gt;근거를 찾아야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;단순하게 유지할 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;똑똑한 사람은 똑똑한 코드를, 훌륭한 사람은 단순한 코드를 씀&lt;/li&gt;
&lt;li&gt;단순한 코드가 유지보수에 훨씬 유리함&lt;/li&gt;
&lt;li&gt;복잡함이 필요한 상황과 아닌 상황을 구별할 줄 알아야 진짜 실력임&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;마무리 생각&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #fbfbfb; color: #555555; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 글은 체크리스트가 아니며, 훌륭한 엔지니어링은 경쟁이 아님&lt;/li&gt;
&lt;li&gt;단, 어려운 작업을 건너뛸 수 있다고 스스로를 속이지 말 것&lt;/li&gt;
&lt;li&gt;훌륭한 개발자가 되는 길에 지름길은 없음&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/492</guid>
      <comments>https://bunhere.tistory.com/492#entry492comment</comments>
      <pubDate>Mon, 14 Apr 2025 09:35:24 +0900</pubDate>
    </item>
    <item>
      <title>[책] 모두를 위한 소프트웨어 보안 설계와 구현</title>
      <link>https://bunhere.tistory.com/490</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;1187&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djum9y/btsMgvlkBQ6/KhDi3AkH6zIRv2zSxsNv81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djum9y/btsMgvlkBQ6/KhDi3AkH6zIRv2zSxsNv81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djum9y/btsMgvlkBQ6/KhDi3AkH6zIRv2zSxsNv81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdjum9y%2FbtsMgvlkBQ6%2FKhDi3AkH6zIRv2zSxsNv81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;1187&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;1187&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 직장 상사였던 김영기 멘토님께서 번역하신 책입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 진행중인 책 번역때문에 이제서야 겨우 훝어보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, 책 내용이 저에게 정말 필요한 내용이네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 팀에서 보안과 관련된 일을 하고 있어서 더 그런 듯 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 보안팀 분들과 일을 자주하고 있는데, 항상 궁금했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자가 아닌 보안 엔지니어가 되신 분들은 어떤 지식을 갖춰야 하는 거지?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책에 그 답이 보였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어차피 대부분의 지식은 인터넷을 통해 찾아볼 수 있지만, 우리가 무엇을 찾아야 하는지를 아는 것은 다른 문제입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 단순한 코딩 가이드나, 안티패턴같은 걸 다루는게 아니라, 보안을 위해 다뤄야 할 거의 모든 내용을 A-Z까지 다루는 듯 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 어쩌면 (앞부분은) 원론적이고 학술적인 내용조차 담고 있긴 하지만, 보안에 대한 기초가 부족한 저로서는 보안팀에서 일하는 분들이 하셨던 일련의 업무들이 이해가 되고, 그 분들이 무엇을 하는 지 감을 잡을 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뒷부분은 실제 개발자들이 알아야 할 패턴들에 대한 내용도 담고 있어서 개발을 하는 사람들이라면 다 읽어봐야 할 책이 아닌가 하는 생각이 들었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 제가 번역중인 책 작업으로 인해 꼼꼼히 읽지 못했지만 두고두고 몇번을 정독해야 할 책 리스트에 한권이 추가해두려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>리뷰성 글들</category>
      <category>모두를 위한 소프트웨어 보안 설계와 구현</category>
      <category>보안</category>
      <category>책읽기</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/490</guid>
      <comments>https://bunhere.tistory.com/490#entry490comment</comments>
      <pubDate>Wed, 12 Feb 2025 15:52:15 +0900</pubDate>
    </item>
    <item>
      <title>[1DayTip] 브라우저 자동로그인 기능의 문제점</title>
      <link>https://bunhere.tistory.com/489</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이제 비밀번호가 다양해지고 복잡해지니, 사이트마다 어떤 비번을 설정했는지 기억이 안나는 경우가 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 최근 이런 기사가 나왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/mnews/article/001/0014551370?sid=105&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://n.news.naver.com/mnews/article/001/0014551370?sid=105&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1711100945521&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;KISA &amp;quot;브라우저 자동 로그인 쓰지 말라&amp;quot;&amp;hellip;정보 탈취 범죄 급증&quot; data-og-description=&quot;한국인터넷진흥원(KISA)은 최근 자동 로그인 기능을 악용한 계정 정보 탈취 범죄가 급증함에 따라 8일 과학기술정보통신부와 함께 브라우저 자동 로그인 기능에 대한 사용주의 권고를 발표했다. &quot; data-og-host=&quot;n.news.naver.com&quot; data-og-source-url=&quot;https://n.news.naver.com/mnews/article/001/0014551370?sid=105&quot; data-og-url=&quot;https://n.news.naver.com/mnews/article/001/0014551370?sid=105&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/wW0Zv/hyVAHYXJtn/uYVklmipmNXHb77dkKGAa1/img.jpg?width=800&amp;amp;height=537&amp;amp;face=0_0_800_537,https://scrap.kakaocdn.net/dn/bLKctc/hyVDChpML0/0WTy8mNo1nFeA2orq6Blb1/img.jpg?width=800&amp;amp;height=537&amp;amp;face=0_0_800_537&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/mnews/article/001/0014551370?sid=105&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://n.news.naver.com/mnews/article/001/0014551370?sid=105&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/wW0Zv/hyVAHYXJtn/uYVklmipmNXHb77dkKGAa1/img.jpg?width=800&amp;amp;height=537&amp;amp;face=0_0_800_537,https://scrap.kakaocdn.net/dn/bLKctc/hyVDChpML0/0WTy8mNo1nFeA2orq6Blb1/img.jpg?width=800&amp;amp;height=537&amp;amp;face=0_0_800_537');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;KISA &quot;브라우저 자동 로그인 쓰지 말라&quot;&amp;hellip;정보 탈취 범죄 급증&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;한국인터넷진흥원(KISA)은 최근 자동 로그인 기능을 악용한 계정 정보 탈취 범죄가 급증함에 따라 8일 과학기술정보통신부와 함께 브라우저 자동 로그인 기능에 대한 사용주의 권고를 발표했다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;n.news.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1053&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMkdQI/btsF0sJupiA/10r3l1QfT4IJrloW8Dk0iK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMkdQI/btsF0sJupiA/10r3l1QfT4IJrloW8Dk0iK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMkdQI/btsF0sJupiA/10r3l1QfT4IJrloW8Dk0iK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMkdQI%2FbtsF0sJupiA%2F10r3l1QfT4IJrloW8Dk0iK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1053&quot; height=&quot;648&quot; data-origin-width=&quot;1053&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알다시피 요즘 사용하는 거의 모든 브라우저는 브라우저에 자동로그인이라는 기능을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 그 대부분의 브라우저는 크로미움 기반입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크로미움은 오픈소스입니다. 그 오픈소스에서는 자동로그인 기능 구현이 이렇게 되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 특정 파일에 암호화 키를 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 사용자의 비밀번호를 해당 암호화키로 암호화합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 이 로직을 알고 있는 해커가 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&quot;사용자의 PC에 접근 수정할 수 있다면&quot;&lt;/b&gt;&lt;/span&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;암호화 키&lt;/span&gt;도, 저장된 &lt;span style=&quot;color: #ee2323;&quot;&gt;아이디&lt;/span&gt;/&lt;span style=&quot;color: #ee2323;&quot;&gt;비밀번호&lt;/span&gt;도 모두 알아낼 수 있는 셈입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 실수로라도 악의적인 해커의 이상한 프로그램을 설치하기만 하면 이 정보들을 모두 털리게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KISA에서 권고하는 정보는 아래에서 찾을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://boho.or.kr/kr/bbs/view.do?bbsId=B0000127&amp;amp;nttId=71375&amp;amp;menuNo=205021&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://boho.or.kr/kr/bbs/view.do?bbsId=B0000127&amp;amp;nttId=71375&amp;amp;menuNo=205021&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1711102124441&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;KISA 보호나라&amp;amp;KrCERT/CC&quot; data-og-description=&quot;KISA 보호나라&amp;amp;KrCERT/CC&quot; data-og-host=&quot;www.boho.or.kr&quot; data-og-source-url=&quot;https://boho.or.kr/kr/bbs/view.do?bbsId=B0000127&amp;amp;nttId=71375&amp;amp;menuNo=205021&quot; data-og-url=&quot;http://boho.or.kr:80&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/qULv6/hyVDC2M2r8/xuLmRKoRnu0a2SK1jqB4Lk/img.png?width=270&amp;amp;height=270&amp;amp;face=0_0_270_270,https://scrap.kakaocdn.net/dn/brZsIA/hyVADoIjmC/1iPNvVZYs02hJFYvqniGa1/img.png?width=270&amp;amp;height=270&amp;amp;face=0_0_270_270,https://scrap.kakaocdn.net/dn/fXGgT/hyVDvii8gr/gCPa8fYqUauOmQ2kK0ktu0/img.jpg?width=1098&amp;amp;height=328&amp;amp;face=0_0_1098_328&quot;&gt;&lt;a href=&quot;https://boho.or.kr/kr/bbs/view.do?bbsId=B0000127&amp;amp;nttId=71375&amp;amp;menuNo=205021&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://boho.or.kr/kr/bbs/view.do?bbsId=B0000127&amp;amp;nttId=71375&amp;amp;menuNo=205021&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/qULv6/hyVDC2M2r8/xuLmRKoRnu0a2SK1jqB4Lk/img.png?width=270&amp;amp;height=270&amp;amp;face=0_0_270_270,https://scrap.kakaocdn.net/dn/brZsIA/hyVADoIjmC/1iPNvVZYs02hJFYvqniGa1/img.png?width=270&amp;amp;height=270&amp;amp;face=0_0_270_270,https://scrap.kakaocdn.net/dn/fXGgT/hyVDvii8gr/gCPa8fYqUauOmQ2kK0ktu0/img.jpg?width=1098&amp;amp;height=328&amp;amp;face=0_0_1098_328');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;KISA 보호나라&amp;amp;KrCERT/CC&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;KISA 보호나라&amp;amp;KrCERT/CC&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.boho.or.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;크롬 자동로그인 기능 끄는 법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크롬 자동로그인을 끄는 법은 간단합니다.&lt;br /&gt;chrome://password-manager/settings 에 접속하여 아래 화면에서 비밀번호 저장여부&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;779&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beS182/btsF00y9VK5/gXZF5MrIJp5RTBnp5APRy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beS182/btsF00y9VK5/gXZF5MrIJp5RTBnp5APRy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beS182/btsF00y9VK5/gXZF5MrIJp5RTBnp5APRy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeS182%2FbtsF00y9VK5%2FgXZF5MrIJp5RTBnp5APRy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;779&quot; height=&quot;453&quot; data-origin-width=&quot;779&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비밀번호 저장여부 확인을 끄면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;엣지 자동로그인 기능 끄는 법&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cejaIE/btsF1rXp2V4/uZK9HxZHSq6QjwK48f7dh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cejaIE/btsF1rXp2V4/uZK9HxZHSq6QjwK48f7dh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cejaIE/btsF1rXp2V4/uZK9HxZHSq6QjwK48f7dh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcejaIE%2FbtsF1rXp2V4%2FuZK9HxZHSq6QjwK48f7dh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;928&quot; height=&quot;312&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;edge://wallet/settings 에서 동일하게 끌 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웨일 브라우저의 경우에는 이 기능에 문제가 없습니다. (덜합니다.)&lt;br /&gt;자동로그인을 쓰신다면 웨일 브라우저를 쓰면 좀 더 안전하다고 할 수 있겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/mnews/article/014/0005154263?sid=105&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://n.news.naver.com/mnews/article/014/0005154263?sid=105&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1711101705555&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;브라우저 &amp;lsquo;자동 로그인&amp;rsquo; 정보 탈취 우려 높아져‥&amp;quot;보안 기술 강화 필요&amp;quot;&quot; data-og-description=&quot;최근 브라우저 자동 로그인 기능을 악용한 계정 정보 탈취가 늘어나고 있어 주의가 요구되고 있다. 개인정보 유출 등을 예방하기 위해 자동 로그인 기능 비활성화 등 사용자들은 자체 점검을 철&quot; data-og-host=&quot;n.news.naver.com&quot; data-og-source-url=&quot;https://n.news.naver.com/mnews/article/014/0005154263?sid=105&quot; data-og-url=&quot;https://n.news.naver.com/mnews/article/014/0005154263?sid=105&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cwYndt/hyVDuRedoD/k5c00lJwSYaJ6c5w39uoP0/img.png?width=800&amp;amp;height=401&amp;amp;face=0_0_800_401,https://scrap.kakaocdn.net/dn/dFGU18/hyVDCuXtEX/db62k2yt8kk3xXUdSsuKcK/img.png?width=800&amp;amp;height=401&amp;amp;face=0_0_800_401&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/mnews/article/014/0005154263?sid=105&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://n.news.naver.com/mnews/article/014/0005154263?sid=105&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cwYndt/hyVDuRedoD/k5c00lJwSYaJ6c5w39uoP0/img.png?width=800&amp;amp;height=401&amp;amp;face=0_0_800_401,https://scrap.kakaocdn.net/dn/dFGU18/hyVDCuXtEX/db62k2yt8kk3xXUdSsuKcK/img.png?width=800&amp;amp;height=401&amp;amp;face=0_0_800_401');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;브라우저 &amp;lsquo;자동 로그인&amp;rsquo; 정보 탈취 우려 높아져‥&quot;보안 기술 강화 필요&quot;&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;최근 브라우저 자동 로그인 기능을 악용한 계정 정보 탈취가 늘어나고 있어 주의가 요구되고 있다. 개인정보 유출 등을 예방하기 위해 자동 로그인 기능 비활성화 등 사용자들은 자체 점검을 철&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;n.news.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웨일도 whale://password-manager/settings 에서 똑같이 기능을 끌 수는 있습니다만,&lt;br /&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;위와 같은 형태의 키 탈취보다는 조금 더 어려운 보안 수준을 갖고 있습니다.&lt;br /&gt;(쉽게 말해 내부적으로 좀 더 보완했습니다.)&lt;br /&gt;&lt;br /&gt;외부에 공개가 안된 로직을 이용하니 단순하 쉽게 탈취하긴 어려운 셈입니다.&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(업데이트 25년)&lt;br /&gt;최신 크로미움은 이 부분을 방어하는 AppBoundEncryption 기능을 추가로 제공하고 있습니다.&lt;br /&gt;물론, 모든 경우에 적용되는 것은 아니고 윈도우즈의 일반적인 설치환경에서는 이 방식으로 암호화를 합니다.&lt;br /&gt;앱별로 암호화를 따로 하는 방식으로 기존처럼 아주 쉽게 탈취할 수는 없을 듯 합니다.&lt;br /&gt;&lt;br /&gt;다만, 이미 저장된 비밀번호들은 그대로 사용될 수 있습니다.&lt;/p&gt;</description>
      <category>컴퓨터 사용 팁</category>
      <category>1day computer tip</category>
      <category>보안위험</category>
      <category>비밀번호 보안</category>
      <category>자동 로그인</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/489</guid>
      <comments>https://bunhere.tistory.com/489#entry489comment</comments>
      <pubDate>Fri, 22 Mar 2024 19:05:10 +0900</pubDate>
    </item>
    <item>
      <title>[1DayTip] 브라우저 탭과 히스토리 빨리 찾기 - Ctrl + shift + a</title>
      <link>https://bunhere.tistory.com/488</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;얼마나 많은 탭을 열어두고 쓰시나요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전 갈수록 탭이 많아 집니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ADns4/btsFWrDO6w0/03CdV9oR9Rvv4XZg2vDux0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ADns4/btsFWrDO6w0/03CdV9oR9Rvv4XZg2vDux0/img.png&quot; data-alt=&quot;이것보다 많이 열어둡니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ADns4/btsFWrDO6w0/03CdV9oR9Rvv4XZg2vDux0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FADns4%2FbtsFWrDO6w0%2F03CdV9oR9Rvv4XZg2vDux0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;728&quot; height=&quot;109&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;109&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이것보다 많이 열어둡니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탭을 닫는 것도 일입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 일을 해주는 익스텐션도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 근본적으로 탭을 여러개 여는 습관부터 고쳐야겠죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새 탭을 열기전에 열려있는 탭이 있는지 찾아보면 어떨까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 사용하는 단축키가 ctrl + shift + a 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모던 브라우저들도 비슷한 UI가 뜨는 걸 볼 수 있습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;웨일&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;크롬&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;엣지&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;브레이브&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1aVJU/btsFX6FnBuG/EtfaKEiCkSXHVA76wxwmFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1aVJU/btsFX6FnBuG/EtfaKEiCkSXHVA76wxwmFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1aVJU/btsFX6FnBuG/EtfaKEiCkSXHVA76wxwmFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1aVJU%2FbtsFX6FnBuG%2FEtfaKEiCkSXHVA76wxwmFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;255&quot; height=&quot;202&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;333&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Eu2s2/btsFXbUOUig/kOiEzbu0VM6hRQ21wkPgr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Eu2s2/btsFXbUOUig/kOiEzbu0VM6hRQ21wkPgr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Eu2s2/btsFXbUOUig/kOiEzbu0VM6hRQ21wkPgr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEu2s2%2FbtsFXbUOUig%2FkOiEzbu0VM6hRQ21wkPgr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;333&quot; height=&quot;272&quot; data-origin-width=&quot;333&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmwJfg/btsFWsW3tAI/Zol9RopAGBNfb3CjSdkweK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmwJfg/btsFWsW3tAI/Zol9RopAGBNfb3CjSdkweK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmwJfg/btsFWsW3tAI/Zol9RopAGBNfb3CjSdkweK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmwJfg%2FbtsFWsW3tAI%2FZol9RopAGBNfb3CjSdkweK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;379&quot; height=&quot;210&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfRtTB/btsFYFUVvMp/jsnR0dSSHv41KmU59RGYx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfRtTB/btsFYFUVvMp/jsnR0dSSHv41KmU59RGYx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfRtTB/btsFYFUVvMp/jsnR0dSSHv41KmU59RGYx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfRtTB%2FbtsFYFUVvMp%2FjsnR0dSSHv41KmU59RGYx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;353&quot; height=&quot;197&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;열린 탭과 과거에 닫은 탭을 모두 보여줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옴니박스에 바로 입력하는 습관에서 ctrl + shift + tab 을 통해 탭 검색을 한 뒤에 없을 경우 ctrl+t (새탭) ctrl+n(새창)을 띄우는 건 어떨까요?&lt;/p&gt;</description>
      <category>컴퓨터 사용 팁</category>
      <category>1day computer tip</category>
      <category>단축키 팁</category>
      <category>브라우저 팁</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/488</guid>
      <comments>https://bunhere.tistory.com/488#entry488comment</comments>
      <pubDate>Thu, 21 Mar 2024 07:47:21 +0900</pubDate>
    </item>
    <item>
      <title>[1DayTip] 스타일없이 붙여넣기 - Ctrl + shift + v 아시나요</title>
      <link>https://bunhere.tistory.com/487</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;요새 다크모드로 글을 많이 씁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 다크모드로 쓴 글을 웹의 Rich editor에 붙일때 검은색이 그대로 붙는 경우가 있습니다.&lt;br /&gt;(무조건 그런건 아닙니다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HrKcI/btsFVsa56AA/xoh4tuJnKq9rnsWCsZhGO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HrKcI/btsFVsa56AA/xoh4tuJnKq9rnsWCsZhGO0/img.png&quot; data-alt=&quot;이 html 파일을 ctrl + c 해서 ctrl + v 하면 어떻게 될까요?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HrKcI/btsFVsa56AA/xoh4tuJnKq9rnsWCsZhGO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHrKcI%2FbtsFVsa56AA%2Fxoh4tuJnKq9rnsWCsZhGO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;395&quot; height=&quot;140&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이 html 파일을 ctrl + c 해서 ctrl + v 하면 어떻게 될까요?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ctrl + v 로 붙이면 이렇게 됩니다.&lt;/p&gt;
&lt;div style=&quot;background-color: #1f1f1f; color: #cccccc;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #808080;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;doctype&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #808080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #808080;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color: #808080;&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;charset&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color: #808080;&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color: #808080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #808080;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #808080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;이 글을 붙여넣으면?&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #808080;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #808080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ctrl + shift + v로 붙이면 이렇게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;doctype&amp;nbsp;html&amp;gt; &lt;br /&gt;&amp;lt;head&amp;gt;&amp;lt;meta&amp;nbsp;charset=&quot;utf-8&quot;&amp;gt;&amp;lt;/head&amp;gt; &lt;br /&gt;&amp;lt;body&amp;gt;이&amp;nbsp;글을&amp;nbsp;붙여넣으면? &lt;br /&gt;&amp;lt;/body&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차이가 바로 느껴지실 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 프로그램이 ctrl + shift + v를 지원하진 않습니다.&lt;br /&gt;아마 대부분의 모던 브라우저들은 지원할겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엑셀 같은 경우가 문제인데, 버전에 따라 지원하지 않는 경우가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 경우 ctrl + alt + v를 시도해보는 것도 방법입니다.&lt;br /&gt;( ctrl + at + v 누른뒤 화살표키 아래 &amp;gt; 엔터)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;116&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oLsQE/btsFWu0zB04/X14PzE9vg0vsfNkAzoEMP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oLsQE/btsFWu0zB04/X14PzE9vg0vsfNkAzoEMP1/img.png&quot; data-alt=&quot;원본 : ctrl+v : ctrl+shift+v&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oLsQE/btsFWu0zB04/X14PzE9vg0vsfNkAzoEMP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoLsQE%2FbtsFWu0zB04%2FX14PzE9vg0vsfNkAzoEMP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;402&quot; height=&quot;116&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;116&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;원본 : ctrl+v : ctrl+shift+v&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>컴퓨터 사용 팁</category>
      <category>1day computer tip</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/487</guid>
      <comments>https://bunhere.tistory.com/487#entry487comment</comments>
      <pubDate>Wed, 20 Mar 2024 10:23:46 +0900</pubDate>
    </item>
    <item>
      <title>워드프레스에서 우편번호 오류창 해결하기</title>
      <link>https://bunhere.tistory.com/484</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JC73u/btsuREMHdkE/YKfquMia3Ag61gsQXKbb60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JC73u/btsuREMHdkE/YKfquMia3Ag61gsQXKbb60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JC73u/btsuREMHdkE/YKfquMia3Ag61gsQXKbb60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJC73u%2FbtsuREMHdkE%2FYKfquMia3Ag61gsQXKbb60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;408&quot; height=&quot;214&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;214&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;position: absolute;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[우편번호 서비스 로딩 오류] API 로딩시 허용되지 않은 파라미터가 감지되었습니다. 사이트 관리자(개발자)분께서는 가이드페이지( &lt;a href=&quot;https://postcode.map.daum.net/guide&quot;&gt;https://postcode.map.daum.net/guide&lt;/a&gt; )의 기본 사용법을 참고하시어 수정 부탁드립니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;워드프레스로 이런 에러가 나는 경우 해결 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론은 아래 정리했습니다. 과정을 음미하실분만 찬찬히 보세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오픈채팅에서 어떤분이 해결하려고 애쓰는 문제를 도와줬습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전 워드프레스도 모르고 암것도 모르니 일단 인스펙터를 열어봅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;89&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V5IDu/btsuGzMPEMc/VIDQM1kFheuYcGE6enn4tK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V5IDu/btsuGzMPEMc/VIDQM1kFheuYcGE6enn4tK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V5IDu/btsuGzMPEMc/VIDQM1kFheuYcGE6enn4tK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV5IDu%2FbtsuGzMPEMc%2FVIDQM1kFheuYcGE6enn4tK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1047&quot; height=&quot;89&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;89&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;postcode.v2란 애가 문제가 있네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소스코드에서 얘를 찾아봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kboard plugin에 아래와 같은 코드가 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1695118151891&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wp_enqueue_script('daum-postcode', '//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js', array(), NULL, true);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드로 구글링을 해서 아래와 같은걸 찾았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.cosmosfarm.com/threads/document/51932&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.cosmosfarm.com/threads/document/51932&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1695118208118&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;우편번호 서비스 에러발생. - Cosmosfarm&quot; data-og-description=&quot;http://nexttile.kr/?page_id=500&amp;amp;mod=editor&amp;amp;pageid=1 해당페이지에서 주소검색 기능이 에러가 발생됩니다.&amp;nbsp; [에러내용은 아래와 같습니다.] [우편번호 서비스] API 로딩시 허용되지 않은 파라미터가 감지되어 &quot; data-og-host=&quot;www.cosmosfarm.com&quot; data-og-source-url=&quot;https://www.cosmosfarm.com/threads/document/51932&quot; data-og-url=&quot;https://www.cosmosfarm.com/threads/document/51932&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/biB8iT/hyTVUFqhG1/CEuKOKegfOKKrcgQyAmP60/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.cosmosfarm.com/threads/document/51932&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.cosmosfarm.com/threads/document/51932&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/biB8iT/hyTVUFqhG1/CEuKOKegfOKKrcgQyAmP60/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;우편번호 서비스 에러발생. - Cosmosfarm&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;http://nexttile.kr/?page_id=500&amp;amp;mod=editor&amp;amp;pageid=1 해당페이지에서 주소검색 기능이 에러가 발생됩니다.&amp;nbsp; [에러내용은 아래와 같습니다.] [우편번호 서비스] API 로딩시 허용되지 않은 파라미터가 감지되어&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.cosmosfarm.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이걸로는 해결이 안되고, 관련 글들을 쭉 읽었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.cosmosfarm.com/threads/document/64728&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.cosmosfarm.com/threads/document/64728&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695118247336&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;우편번호 API 오류문제 - Cosmosfarm&quot; data-og-description=&quot;1. 정확한 제품 또는 플러그인 이름 코스모스팜 회원관리 2. 상세 내용 일주일 시험버전을 다운받아 설치하였는데&amp;nbsp; 다음과 같은 에러가 발생합니다. 다른 우편번호 관련&amp;nbsp;플러그인은 사용하는게&quot; data-og-host=&quot;www.cosmosfarm.com&quot; data-og-source-url=&quot;https://www.cosmosfarm.com/threads/document/64728&quot; data-og-url=&quot;https://www.cosmosfarm.com/threads/document/64728&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/j9Ljo/hyTY7C7MER/HOFopnkZNptgdrHNi6suT1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.cosmosfarm.com/threads/document/64728&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.cosmosfarm.com/threads/document/64728&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/j9Ljo/hyTY7C7MER/HOFopnkZNptgdrHNi6suT1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;우편번호 API 오류문제 - Cosmosfarm&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 정확한 제품 또는 플러그인 이름 코스모스팜 회원관리 2. 상세 내용 일주일 시험버전을 다운받아 설치하였는데&amp;nbsp; 다음과 같은 에러가 발생합니다. 다른 우편번호 관련&amp;nbsp;플러그인은 사용하는게&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.cosmosfarm.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시가 되서 그런것 같다고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 인스펙터에서 나온 결과를 보면 postcode에 이상한 값이 붙어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 사이트가 캐시 플러그인을 사용하나 봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시 플러그인이 뭐가 있는지 몰라서 워드프레스 캐시 플러그인들을 찾아보니 몇개가 나옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.elegantthemes.com/blog/wordpress/best-wordpress-cache-plugins&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.elegantthemes.com/blog/wordpress/best-wordpress-cache-plugins&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695118385229&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;9 Best WordPress Cache Plugins in 2023 (For Site Speed)&quot; data-og-description=&quot;Caching is a great way to speed up your website, here are our top choices for WordPress Cache plugins in 2023.&quot; data-og-host=&quot;www.elegantthemes.com&quot; data-og-source-url=&quot;https://www.elegantthemes.com/blog/wordpress/best-wordpress-cache-plugins&quot; data-og-url=&quot;https://www.elegantthemes.com/blog/wordpress/best-wordpress-cache-plugins&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dwYZAL/hyTY0qtsZt/NOimqjkb1iKpHHsTlmw2lK/img.jpg?width=1946&amp;amp;height=1096&amp;amp;face=0_0_1946_1096,https://scrap.kakaocdn.net/dn/jb9Fs/hyTY8aXM1K/eukfDk1B77EYnp9V7wxKk1/img.jpg?width=1800&amp;amp;height=1212&amp;amp;face=0_0_1800_1212,https://scrap.kakaocdn.net/dn/hTqEa/hyTZa7G7Qt/PKFCuTWLj6Eh7j22d9kPpK/img.jpg?width=1674&amp;amp;height=1070&amp;amp;face=0_0_1674_1070&quot;&gt;&lt;a href=&quot;https://www.elegantthemes.com/blog/wordpress/best-wordpress-cache-plugins&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.elegantthemes.com/blog/wordpress/best-wordpress-cache-plugins&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dwYZAL/hyTY0qtsZt/NOimqjkb1iKpHHsTlmw2lK/img.jpg?width=1946&amp;amp;height=1096&amp;amp;face=0_0_1946_1096,https://scrap.kakaocdn.net/dn/jb9Fs/hyTY8aXM1K/eukfDk1B77EYnp9V7wxKk1/img.jpg?width=1800&amp;amp;height=1212&amp;amp;face=0_0_1800_1212,https://scrap.kakaocdn.net/dn/hTqEa/hyTZa7G7Qt/PKFCuTWLj6Eh7j22d9kPpK/img.jpg?width=1674&amp;amp;height=1070&amp;amp;face=0_0_1674_1070');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;9 Best WordPress Cache Plugins in 2023 (For Site Speed)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Caching is a great way to speed up your website, here are our top choices for WordPress Cache plugins in 2023.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.elegantthemes.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관련된 플러그인이 설치되었나 확인해봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수많은 플러그인 사이에서 찾았습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;72&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c26Hos/btsuGkB2yzK/EfeZkUzw0VfMEMYKQM0xek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c26Hos/btsuGkB2yzK/EfeZkUzw0VfMEMYKQM0xek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c26Hos/btsuGkB2yzK/EfeZkUzw0VfMEMYKQM0xek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc26Hos%2FbtsuGkB2yzK%2FEfeZkUzw0VfMEMYKQM0xek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;789&quot; height=&quot;72&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;72&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Settings에 들어갑니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CUpYK/btsuJf1iizz/P7pbHpsiSXSra090SgMbu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CUpYK/btsuJf1iizz/P7pbHpsiSXSra090SgMbu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CUpYK/btsuJf1iizz/P7pbHpsiSXSra090SgMbu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCUpYK%2FbtsuJf1iizz%2FP7pbHpsiSXSra090SgMbu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;688&quot; height=&quot;380&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시탭이 있지만 별 세팅이 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대신 FILE OPTIMIZATION에 들어가니 CSS와 JS의 처리방식이 있고 exclude가 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dyOFjD/btsuRDUwcMh/MMQegJVybcTQYmHCrbgDvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dyOFjD/btsuRDUwcMh/MMQegJVybcTQYmHCrbgDvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dyOFjD/btsuRDUwcMh/MMQegJVybcTQYmHCrbgDvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdyOFjD%2FbtsuRDUwcMh%2FMMQegJVybcTQYmHCrbgDvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;626&quot; height=&quot;414&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Javascript 쪽에 postcode.v2.js를 넣고 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네 위 에러가 없어졌고 postcode.js의 url뒤에 뭐가 더이상 안붙게 되었네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발</category>
      <category>다음 우편번호</category>
      <category>다음 우편번호 경고창</category>
      <category>다음 우편번호 오류</category>
      <category>우편번호 경고 오류</category>
      <category>우편번호 오류</category>
      <category>워드프레스 오류</category>
      <category>워드프레스 우편번호 오류</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/484</guid>
      <comments>https://bunhere.tistory.com/484#entry484comment</comments>
      <pubDate>Tue, 19 Sep 2023 19:18:18 +0900</pubDate>
    </item>
    <item>
      <title>카카오톡 오픈 프로필 만들기</title>
      <link>https://bunhere.tistory.com/483</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;몇가지 방법이 있지만, 오픈 채팅방에서 만드는 법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오픈 채팅방 우상단 줄세개를 클릭합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVHN2T/btsf6HcKwy9/e2gmC7Y57JcX4efp8VCKt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVHN2T/btsf6HcKwy9/e2gmC7Y57JcX4efp8VCKt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVHN2T/btsf6HcKwy9/e2gmC7Y57JcX4efp8VCKt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVHN2T%2Fbtsf6HcKwy9%2Fe2gmC7Y57JcX4efp8VCKt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;921&quot; height=&quot;400&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 계정을 클릭합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;1454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsGy9g/btsf2pkiVjo/iuWB72ZBOWrLGHEHZbi2h0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsGy9g/btsf2pkiVjo/iuWB72ZBOWrLGHEHZbi2h0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsGy9g/btsf2pkiVjo/iuWB72ZBOWrLGHEHZbi2h0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsGy9g%2Fbtsf2pkiVjo%2FiuWB72ZBOWrLGHEHZbi2h0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;928&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;1454&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로필 편집 클릭합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;917&quot; data-origin-height=&quot;818&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRBSYv/btsf59AsCzx/x797Rm460wPQxb4i4bFSqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRBSYv/btsf59AsCzx/x797Rm460wPQxb4i4bFSqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRBSYv/btsf59AsCzx/x797Rm460wPQxb4i4bFSqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRBSYv%2Fbtsf59AsCzx%2Fx797Rm460wPQxb4i4bFSqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;917&quot; height=&quot;818&quot; data-origin-width=&quot;917&quot; data-origin-height=&quot;818&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 오픈 프로필 만들기를 선택합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;682&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A1lMJ/btsf3g8crR7/S3df1GFS21ChtHMLkjanv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A1lMJ/btsf3g8crR7/S3df1GFS21ChtHMLkjanv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A1lMJ/btsf3g8crR7/S3df1GFS21ChtHMLkjanv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA1lMJ%2Fbtsf3g8crR7%2FS3df1GFS21ChtHMLkjanv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;947&quot; height=&quot;682&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;682&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적당한 이름을 적고 완료를 누릅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;923&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/68aWP/btsgbLy2BCZ/mK41rYEp9VHA8kqOeHv051/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/68aWP/btsgbLy2BCZ/mK41rYEp9VHA8kqOeHv051/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/68aWP/btsgbLy2BCZ/mK41rYEp9VHA8kqOeHv051/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F68aWP%2FbtsgbLy2BCZ%2FmK41rYEp9VHA8kqOeHv051%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;924&quot; height=&quot;923&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;923&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업데이트 된 것을 확인합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;1364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpuOit/btsgaMkviHA/NwBZHOTxzMDzCD7MhG3xtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpuOit/btsgaMkviHA/NwBZHOTxzMDzCD7MhG3xtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpuOit/btsgaMkviHA/NwBZHOTxzMDzCD7MhG3xtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpuOit%2FbtsgaMkviHA%2FNwBZHOTxzMDzCD7MhG3xtk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;818&quot; height=&quot;1364&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;1364&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>컴퓨터 사용 팁</category>
      <category>오픈프로필만들기</category>
      <category>카카오톡 오픈프로필</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/483</guid>
      <comments>https://bunhere.tistory.com/483#entry483comment</comments>
      <pubDate>Tue, 16 May 2023 12:23:38 +0900</pubDate>
    </item>
    <item>
      <title>[책] 오늘도 개발자가 안 된다고 말했다</title>
      <link>https://bunhere.tistory.com/482</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;책을 읽고 난 느낀점 정리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 뭐랄까 개발자가 뭔가 외계인도 아니고, 선망의 대상도 아닐진데 뭔가 다른 세상 사람인것처럼 대하는 글의 느낌이 매우 신선하게 다가왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 어딘가 이상한 비전공자의 협업&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기획자 김군의 협업&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 구조와 인체 구조의 닮은 점 중에서&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;423&quot; data-origin-height=&quot;228&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TkE0s/btr9rhGP3On/fgQTh8EK3HHi8DoYnGoDu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TkE0s/btr9rhGP3On/fgQTh8EK3HHi8DoYnGoDu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TkE0s/btr9rhGP3On/fgQTh8EK3HHi8DoYnGoDu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTkE0s%2Fbtr9rhGP3On%2FfgQTh8EK3HHi8DoYnGoDu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;423&quot; height=&quot;228&quot; data-origin-width=&quot;423&quot; data-origin-height=&quot;228&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 비유가 이상하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;증상을 파악하고 처방을 한다는 부분은 인체(의학?)와 비슷하다는 건 어느정도 공감이 가는데,&lt;br /&gt;위처럼 분류한 것은 오해의 소지가 많아 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;개발자끼리도 생각이 다르다&quot; 중에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사람이니까 당연히 서로 생각하는 바가 다른게 당연하다. 특히 뭐든 낙관적인 사람도 있고 비관적인 사람도 있다.&lt;br /&gt;다만 개발에서 요청을 받아들일 때 기간과 가능성을 정할때는 그저 POC수준에서 구현하는 것인지, 아니면 실제 서비스로 써야 하는지에 따라 기간과 가능성이 정말 많이 달라질 수 밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이 부분에 대해서 개발자마다의 차이가 있으니 당연히 오랜 시간 함께 지내다보면 그 개발자가 어떤 성향인지 알게 되고 개발자의 성향에 맞는 대응이 생기는 것은 당연한 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디자이너 김 양의 협업&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과거에 psd 파일을 직접 받아서 잘라서 웹사이트를 만들던 시절이 실제로 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;직접 개발해볼 수 있지 않을까?라는 착각&quot; 중에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디자이너가 개발을 공부하는 것에 대한 부분이 나왔는데 십분 공감이 간다. 나는 구현을 생각하는 경향이 있다. 이 틀을 깨고 디자인과 개발을 나눠서 할 수 있다면 좋겠는데, 나는 개발 한번 배워 보는 건 어때요? 라고 말을 건넬때 정말로 개발을 해보라는 의미였는데, 구조를 이해하는 수준으로 배우란 의미로 생각한다는 것도 신기하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;우리가 협업을 할 수 있었던 이유&quot; 에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;무식하면 용감하다는 말이 있듯이 아무것도 몰랐기 때문에 개발자의 말에 더 경청할 수 있었고, 이해되지 않는 내용은 질문을 반복하면서 협업을 위해 알고 있어야 하는 정보가 무엇인지 빠르게 학습할 수 있었다. 이른바 소통하기 위해 소통을 했던 것이다.&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 이 문장이 개발자와 아니, 거의 모든 다른 도메인과 협업해야 하는 사람들의 마음속에 담아야 할 핵심 문장이 아닌가 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;심지어 같은 개발자라고 하더라도 경청하는 마음과 배우는 마음으로 협업한다면 비록 문제를 해결하진 못해도 협업의 과정에서의 문제는 사라지지 않을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 온몸으로 느낀 개발자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세가지 유형의 개발자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 안된다고 말을 달고 사는 개발자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1, 서비스 구조를 고려하지 않고 개발을 요청하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 안정성에 영향을 주는 개발 건을 요청하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 쌓인 일이 많을 때 개발을 요청하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 세가지 만은 아닐것 같은데 중요한 세가지 지점같다. 네번째로 중요하지 않아 보이는데 만들기 어렵고(하기싫은) 경우가 있지 않나 싶다. 1번과 겹치는 것 같기도 하지만, 서비스 구조와 겹치지 않더라도 그냥 개발자가 만들기 싫은 경우도 있다고 생각한다. (개발자도 그냥 평범한 사람이고 게으른 사람도 많다. 나...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 무엇이든 가능하다고 말하는 개발자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 기능의 구현 가능 여부만 놓고 대답하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 자신의 업무만 한정지어 가능하다고 하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세번째가 빠진 것 같다. 경험이 적은 신입인 경우. 어느정도 경력이 쌓인 개발자가 무엇이든 가능하다고 말할리가 없다. 반대로 소프트웨어의 세상에서 불가능한것도 사실 없다. 단지 제한된 자원으로 가능하냐의 문제가 첫번째고, 그걸 내가 해야 한다는게 두번째이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누군가 사장을 제외하고 같은 급여로 52시간 일하던 이에게 120시간 일하라고 하면 그냥 네 하고 일할 사람이 얼마나 될까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자에게 가능하다. 라는 대답은 나에게 그 의무가 부여되는 것과 같다. 그 무게를 알 수록 무엇이든 가능하다고 대답할 수는 없을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대안을 제안하는 개발자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞에서도 말했지만 많은 것들이 협업을 한다면 당연히 해야 할 일이라고 생각한다. 누군가의 의견에 안되요. 가 아니라 안되면 대안을 제시하는 것이 맞다. 개발자가 부정적으로 보이는 이유는 안된다에서 끝나는 경우가 많기 때문이 아닐까? 물론 대안을 제시한다는 것조차 언젠가부터 잘 생각하게 된다. 앞에도 말했지만 그 대안이 나의 의무가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 때론 그 일을 실제 개발하지 않을 동료 개발자나 개발팀장같은 사람이 필요해진다. 직접 구현을 하진 않으며 대안을 제안하는 협업능력을 갖춘 사람이다. 의무에 대한 부담없이 개발 가능성을 이야기할 수 있지 않을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;협업을 잘하는 개발자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 집요한 문제해결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 비즈니스를 이해하는 눈&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 쉽게 말하는 소통의 기술&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 체계적인 업무 관리와 빠른 피드백&lt;/p&gt;</description>
      <category>리뷰성 글들</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/482</guid>
      <comments>https://bunhere.tistory.com/482#entry482comment</comments>
      <pubDate>Tue, 11 Apr 2023 23:39:36 +0900</pubDate>
    </item>
    <item>
      <title>FE공부2 - 웹스토리보이님의 레이아웃02 영상</title>
      <link>https://bunhere.tistory.com/481</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=dNQZqNd_uUE&quot;&gt;https://www.youtube.com/watch?v=dNQZqNd_uUE&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=dNQZqNd_uUE&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/b4Colr/hyQYAHT2Le/AdvSxY1pyqvy9b47JsRzak/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/dNQZqNd_uUE&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난번 영상과 큰 차이가 없는 것 같네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, overflow: hidden 에 대해 이야기를 하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버그라고 이야기를 하고 있는데, 버그 아니라 표준입니다;;&lt;br /&gt;(물론 웹 표준이 구현에 구겨 맞춰 만들어진 감이 있긴 합니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.w3.org/TR/CSS2/visuren.html#block-formatting&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.w3.org/TR/CSS2/visuren.html#block-formatting&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671458210312&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Visual formatting model&quot; data-og-description=&quot;In the visual formatting model, each element in the document tree generates zero or more boxes according to the box model. The layout of these boxes is governed by: The visual formatting model does not specify all aspects of formatting (e.g., it does not s&quot; data-og-host=&quot;www.w3.org&quot; data-og-source-url=&quot;https://www.w3.org/TR/CSS2/visuren.html#block-formatting&quot; data-og-url=&quot;https://www.w3.org/TR/CSS2/visuren.html#block-formatting&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bOosgm/hyQWy5ZocU/sA92t7rk1ChOw6STA4SLk0/img.png?width=407&amp;amp;height=263&amp;amp;face=0_0_407_263,https://scrap.kakaocdn.net/dn/F99VC/hyQWy5ZodD/Ib8uHnNN678fxyzsn3ExK0/img.png?width=318&amp;amp;height=306&amp;amp;face=0_0_318_306,https://scrap.kakaocdn.net/dn/tMJJN/hyQYG2p5QW/9c2UeZ7vLX6C3T1iSKtve0/img.png?width=319&amp;amp;height=286&amp;amp;face=0_0_319_286&quot;&gt;&lt;a href=&quot;https://www.w3.org/TR/CSS2/visuren.html#block-formatting&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.w3.org/TR/CSS2/visuren.html#block-formatting&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bOosgm/hyQWy5ZocU/sA92t7rk1ChOw6STA4SLk0/img.png?width=407&amp;amp;height=263&amp;amp;face=0_0_407_263,https://scrap.kakaocdn.net/dn/F99VC/hyQWy5ZodD/Ib8uHnNN678fxyzsn3ExK0/img.png?width=318&amp;amp;height=306&amp;amp;face=0_0_318_306,https://scrap.kakaocdn.net/dn/tMJJN/hyQYG2p5QW/9c2UeZ7vLX6C3T1iSKtve0/img.png?width=319&amp;amp;height=286&amp;amp;face=0_0_319_286');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Visual formatting model&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In the visual formatting model, each element in the document tree generates zero or more boxes according to the box model. The layout of these boxes is governed by: The visual formatting model does not specify all aspects of formatting (e.g., it does not s&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.w3.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSS 2.1 표준을 보면,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;overflow가 visible이 아닌, block은 새로운 block formatting context를 만듭니다..&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;그럼 container 의 height는 지정하지 않으면(auto) 어떻게 계산될까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;a href=&quot;https://www.w3.org/TR/CSS21/visudet.html#root-height&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.w3.org/TR/CSS21/visudet.html#root-height&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671458436839&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Visual formatting model details&quot; data-og-description=&quot;The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block of an element is defined as follows: In paged media, an absolutely positioned element i&quot; data-og-host=&quot;www.w3.org&quot; data-og-source-url=&quot;https://www.w3.org/TR/CSS21/visudet.html#root-height&quot; data-og-url=&quot;https://www.w3.org/TR/CSS21/visudet.html#root-height&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.w3.org/TR/CSS21/visudet.html#root-height&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.w3.org/TR/CSS21/visudet.html#root-height&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Visual formatting model details&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block of an element is defined as follows: In paged media, an absolutely positioned element i&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.w3.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;In certain cases (see, e.g., sections&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height&quot;&gt;10.6.4&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://www.w3.org/TR/CSS21/visudet.html#block-root-margin&quot;&gt;10.6.6&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;above), the height of an element that establishes a block formatting context is computed as follows:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;If it only has inline-level children, the height is the distance between the top of the topmost line box and the bottom of the bottommost line box.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;If it has block-level children, the height is the distance between the top margin-edge of the topmost block-level child box and the bottom margin-edge of the bottommost block-level child box.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Absolutely positioned children are ignored, and relatively positioned boxes are considered without their offset. Note that the child box may be an&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://www.w3.org/TR/CSS21/visuren.html#anonymous-block-level&quot;&gt;anonymous block box.&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In addition, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;if the element has any floating descendants whose bottom margin edge is below the element's bottom content edge, then the height is increased to include those edges.&lt;/b&gt;&lt;/span&gt; Only floats that participate in this block formatting context are taken into account, e.g., floats inside absolutely positioned descendants or other floats are not.&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;height가 auto일 때 block의 크기는 topmost 블럭이랑 bottommost 블럭이 결정합니다. &lt;span style=&quot;color: #ee2323;&quot;&gt;다만 float이 있으면 그만큼 늘어납니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, overflow로 인해 새 block formating context가 시작되었고, 그 block formating context의 크기가 float을 포함했기 때문에 해당 block formating context의 크기가 float크기만큼 커져서 결정된 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 overflow를 준 container block (영상에서 main) 에 height를 임의로 지정한다면, 다음 block은 float을 무시하지 않기 때문에 겹쳐 보이게 될 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면, clear는 현재의 block formating context이전의 float box와 연관되지 않게 하는 프로퍼티입니다.&lt;br /&gt;따라서 main의 height를 지정하더라도 겹쳐 보이지 않게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍 언어/Web</category>
      <category>clear와 overflow:hidden의 차이</category>
      <category>css 2.1 float</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/481</guid>
      <comments>https://bunhere.tistory.com/481#entry481comment</comments>
      <pubDate>Mon, 19 Dec 2022 23:28:56 +0900</pubDate>
    </item>
    <item>
      <title>FE공부1 - 웹스토리보이님의 레이아웃01 영상</title>
      <link>https://bunhere.tistory.com/480</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;SE-92456263-439c-4281-b9aa-cea9328ca4d6&quot; data-compid=&quot;SE-92456263-439c-4281-b9aa-cea9328ca4d6&quot; data-a11y-title=&quot;본문&quot;&gt;
&lt;div&gt;
&lt;div data-unitid=&quot;&quot; data-compid=&quot;SE-92456263-439c-4281-b9aa-cea9328ca4d6&quot; data-direction=&quot;top&quot;&gt;
&lt;div id=&quot;SE-d0de0fdf-f3fe-46d4-b888-a40a04b864b5&quot;&gt;
&lt;p id=&quot;SE-a253ff64-dc20-46f2-bddf-8231c24f24ac&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-href=&quot;https://www.youtube.com/watch?v=qnwa6I5WosI&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=qnwa6I5WosI&quot;&gt;https://www.youtube.com/watch?v=qnwa6I5WosI&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=qnwa6I5WosI&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/b7VHRC/hyQTBalBe2/yfZv3HrKfkliwO8frmSpkK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/qnwa6I5WosI&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;[레이아웃01] 사이트 만들기 프로젝트1 - float, flex, grid 레이아웃 유형별 연습하기&quot; 라는 제목을 갖고 있는데,&lt;br /&gt;내용은 레이아웃 만져보기 정도였습니다.&lt;br /&gt;그래도 궁금한건 직접 찾아서 공부해보면 되서 나쁘지 않았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; letter-spacing: 0px;&quot;&gt;언급된 내용들 중 중요하다고 생각되는 것들을 기초적으로만 정리해보면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- float &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot; data-href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/float&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/float&quot;&gt;https://developer.mozilla.org/ko/docs/Web/CSS/float&lt;/a&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;div id=&quot;SE-d4947ed1-8ed5-4513-aabd-d61bd1041999&quot; data-compid=&quot;SE-d4947ed1-8ed5-4513-aabd-d61bd1041999&quot; data-a11y-title=&quot;본문&quot;&gt;
&lt;div data-unitid=&quot;&quot; data-compid=&quot;SE-d4947ed1-8ed5-4513-aabd-d61bd1041999&quot; data-direction=&quot;top&quot;&gt;
&lt;div id=&quot;SE-f5b51bd2-9b87-490b-b89e-062bf545d831&quot;&gt;
&lt;p id=&quot;SE-bde0c616-98e0-42ce-a8dc-43c9a7955702&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;CSS 속성(property)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;&lt;b&gt;float&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;은 한 요소(element)가 보통 흐름(normal flow)으로부터 빠져 텍스트 및 인라인(inline) 요소가 그 주위를 감싸는 자기 컨테이너의 좌우측을 따라 배치되어야 함을 지정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;SE-bf933a13-7ccd-4839-a6b8-5722bf664ffb&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;- clear&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot; data-href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/clear&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/clear&quot;&gt;https://developer.mozilla.org/ko/docs/Web/CSS/clear&lt;/a&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p id=&quot;SE-a4106ebf-0727-412e-ba2c-a5d2b53bb884&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot; data-href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS&quot;&gt;&lt;u&gt;CSS&lt;/u&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;속성은 요소가 선행&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot; data-href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/float&quot;&gt;&lt;u&gt;부동&lt;/u&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;(floating) 요소 다음일 수 있는지 또는 그 아래로 내려가(해제되어(cleared))야 하는 지를 지정합니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #1b1b1b;&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;속성은 부동 및 비부동 요소 모두에 적용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;SE-31911dad-3533-45c0-8718-417d8cb4f1a3&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;- media query&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot; data-href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries&lt;/a&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p id=&quot;SE-edb702b1-b572-4a8e-85db-74da66b14a89&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;@로 시작&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;어떤 CSS를 미디어의 유형에 따라 선택적으로 사용하고 싶을 때 사용&lt;br /&gt;영상에서 screen 생략 가능하다 이런 이야기가 있는데, 이건 틀린 이야기일 겁니다.&lt;br /&gt;print media가 큰 의미가 없어졌긴 합니다만, print 화면을 다르게 출력하려고 한다면 해당 값을 이용해야 합니다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-f9c71e3f-3a4c-40e0-9bed-68aa6eaad0c2&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;media type : all screen print&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;media feature : min-width max-width color orientation ...&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-438c7bb3-666e-42f3-830f-e67d916d874a&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;and 나 or로 묶을 수 있음 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;, 로 여러개 쓸 수 있음&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;SE-d6b61123-8e2e-4a62-af01-f3aa874759ae&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;- flex&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot; data-href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/flex&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/flex&quot;&gt;https://developer.mozilla.org/ko/docs/Web/CSS/flex&lt;/a&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p id=&quot;SE-df9a5420-34bf-4713-9122-c304873b9b30&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;CSS가 엘리먼트들을 배치(layout)하는 방법들 가운데, 기존의 block 이나 inline 외에 도입한 방법입니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;기존의 보통흐름을 위해 사용되던 block과 inline과 달리, 자식을 어떻게 배치할지를 지정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;span style=&quot;color: #1b1b1b;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;flex의 기본은 자식들을 배치하는 방향입니다. 영상에서는 기본 방향 row에 flex-wrap을 사용했습니다.&lt;/span&gt;&lt;/span&gt;
&lt;p id=&quot;SE-db9f7c8a-027b-4118-856a-5c4f2a3715e9&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot; data-href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Flexible_Box_Layout&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Flexible_Box_Layout&quot;&gt;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Flexible_Box_Layout&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;flex 관련 잘 정리된 글 :&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;&lt;a href=&quot;https://studiomeal.com/archives/197&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://studiomeal.com/archives/197&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;SE-61669836-e289-4a3a-8f45-60c7899f9093&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;- grid&lt;/span&gt;&lt;/h4&gt;
&lt;p id=&quot;SE-a37e72f5-327f-45e9-8b53-c89dd30c7aef&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;flex처럼 자식을 어떻게 배치할지를 정하는데, 테이블레이아웃처럼 2차원으로 배치하기 위해 만들어진 방법입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-c4d68c27-6e78-4986-aa4c-40865b5aac53&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot; data-href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Grid_Layout&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Grid_Layout&quot;&gt;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Grid_Layout&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-bc53a471-8f24-443f-9d2b-a38c4d429af5&quot; data-ke-size=&quot;size16&quot;&gt;grdi 좀 어렵지만 정리된 글 : &lt;a href=&quot;https://studiomeal.com/archives/533&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://studiomeal.com/archives/533&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍 언어/Web</category>
      <category>FE 스터디</category>
      <category>웹스토리보이</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/480</guid>
      <comments>https://bunhere.tistory.com/480#entry480comment</comments>
      <pubDate>Thu, 15 Dec 2022 00:24:32 +0900</pubDate>
    </item>
    <item>
      <title>ninja 빌드시 반복적으로 gn이 호출됨</title>
      <link>https://bunhere.tistory.com/479</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;원인을 모르게 gn이 반복적으로 호출됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-d explain 옵션을 주고 실행해보니 시간 정보가 바뀌지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ls로 해당 파일을 확인해보니 시간 정보가 이상함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;drwxrwxr-x 265 ryuan ryuan 28672 11월 3 14:17 .&lt;br /&gt;drwxrwxr-x 27 ryuan ryuan 4096 11월 2 15:46 ..&lt;br /&gt;-rw-rw-r-- 1 ryuan ryuan 406205 11월 3 &lt;b&gt;2022&lt;/b&gt; BUILD.gn&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 지우고 다시 받으니 괜찮음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것때문에 한참 삽질했다;&lt;/p&gt;</description>
      <category>개발</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/479</guid>
      <comments>https://bunhere.tistory.com/479#entry479comment</comments>
      <pubDate>Tue, 8 Nov 2022 11:02:09 +0900</pubDate>
    </item>
    <item>
      <title>[Crawling] BeautifulSoup 예제</title>
      <link>https://bunhere.tistory.com/478</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오픈 채팅방에서 Beautiful soup 예제에 대한 설명을 원하는 분이 계셔서 간단히 공부하고 작성해 봅니다.&lt;br /&gt;(BeautifulSoup 처음 써봄)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BeautifulSoup은 HTML/XML 데이터를 가져와서 간단히 파싱을 해서 보여주는 python 라이브러리입니다.&lt;br /&gt;&lt;a href=&quot;https://www.crummy.com/software/BeautifulSoup/bs4/doc/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.crummy.com/software/BeautifulSoup/bs4/doc/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PIP로 설치할 수 있습니다. &lt;a href=&quot;https://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-beautiful-soup&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-beautiful-soup&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 예제는 다음과 같습니다.&lt;br /&gt;이 블로그의 목록을 가져와 제목과 요약을 출력해보았습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1660176735481&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.141 Safari/537.36'}
data = requests.get('https://bunhere.tistory.com/',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

articles = soup.select('.area-main &amp;gt; .area-common &amp;gt; article')
for article in articles:
    title = article.select_one('.title')
    summary = article.select_one('.summary')
    print(title.text, summary.text)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코딩을 거의 모른다고 전제하고 하나씩 설명해 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;처음 두 줄은 python에서 외부 라이브러리(또는 모듈)를 가져오는 부분입니다.&lt;/b&gt;&lt;br /&gt;우리가 직접 작성하지 않은 코드들을 가져와 사용하고 싶을 때 파이썬에서는 import라는 키워드를 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫번째 줄은 requests라는 외부모듈을 가져옵니다. 이걸로 네트워크를 통해 웹페이지를 가져올 겁니다.&lt;br /&gt;두번째 줄은 bs4 라는 외부 모듈에서 BeautifulSoup을 가져옵니다. 부분적으로 가져오기 위해 from 이라는 키워드를 사용했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그 다음 코드 블럭 4-5줄은 네트워크를 통해 html을 가져오는 부분입니다.&lt;/b&gt;&lt;br /&gt;requests라는 모듈은 get이라는 함수를 가지고 있습니다. 웹에서 어떤 정보를 요청하는 가장 기본적인 두가지 메소드(get과 post)중 get을 이용해 웹페이지 정보를 가져오는 일을 수행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 브라우저를 통해 주소를 전달할때 브라우저는 주소외에 다른 정보들을 추가로 전달합니다.&lt;br /&gt;이 것을 request header라고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;735&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rAuZ8/btrJrQeZGIS/9Cuy50llNC6YTNuwzGrGq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rAuZ8/btrJrQeZGIS/9Cuy50llNC6YTNuwzGrGq1/img.png&quot; data-alt=&quot;브라우저의 인스펙터를 통해 Request header 정보를 볼 수 있습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rAuZ8/btrJrQeZGIS/9Cuy50llNC6YTNuwzGrGq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrAuZ8%2FbtrJrQeZGIS%2F9Cuy50llNC6YTNuwzGrGq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1019&quot; height=&quot;735&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;735&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;브라우저의 인스펙터를 통해 Request header 정보를 볼 수 있습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 전달된 request header 정보들은 url과 함께 웹서버가 적절히 판단하여 결과를 보내주게 됩니다. 이 중 웹 서버들이 확인하는 주요 정보중 하나인 User-Agent는 이 요청이 누구에게서 왔는지 알려주는 역할을 수행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저에서 요청한 것처럼 해야 하기 때문에 유명한 브라우저의 User-Agent 정보를 임의로 하나 header에 넣어 전달하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7줄은 beatiful soup을 객체를 만듭니다.&lt;/b&gt;&lt;br /&gt;requests 모듈의 get 함수를 통해 받은 html data를 넘겨주고, html.parser를 사용할 것을 선언합니다&lt;br /&gt;&lt;a href=&quot;https://www.crummy.com/software/BeautifulSoup/bs4/doc/#making-the-soup&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.crummy.com/software/BeautifulSoup/bs4/doc/#making-the-soup&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그 뒤로 beautiful soup을 이용하여 html의 특정 요소들의 내용을 찾아 꺼내와야 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것을 수행하려면 html 과 CSS 선택자에 대해 이해가 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 웹 페이지는 HTML, CSS, JavaScript 이렇게 세가지 요소로 이루어져 있습니다.&lt;br /&gt;크롤링을 위해 꼭 필요한 기본 적인 정보만 설명해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTML은 hypertext markup language의 줄임말로 HTML 파일은 HTML 태그라고 불리는 마크업들을 텍스트 문서로 나열한 것입니다.&lt;br /&gt;태그들은 &amp;lt;body&amp;gt; ... &amp;lt;/body&amp;gt; 와 같이 대체로 여는 태그와 닫는 태그로 구성되어 있습니다.&lt;br /&gt;이 태그들을 중첩해서 웹페이지가 담으려는 정보들의 구조를 잡게 됩니다.&lt;br /&gt;크롤링을 위해 알아야 하는 HTML의 또 다른 중요한 요소는 어트리뷰트(attribute)입니다. 어트리뷰트는 태그에 추가적인 속성을 제공합니다. 그렇게 제공되는 속성 가운데 id와 class가 크롤링을 위해 많이 사용됩니다.&lt;br /&gt;id ( &lt;a href=&quot;https://www.w3schools.com/html/html_id.asp&quot;&gt;https://www.w3schools.com/html/html_id.asp&lt;/a&gt; )는 특정 태그를 유일하게 구분할 수 있게 해주며,&lt;br /&gt;class ( &lt;a href=&quot;https://www.w3schools.com/html/html_classes.asp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.w3schools.com/html/html_classes.asp&lt;/a&gt; )는 특정 태그들의 묶음을 구분할 수 있게 해줍니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1660179772586&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;body&amp;gt; ... &amp;lt;a href=&quot;...&quot; id=&quot;link_axxx&quot; class=&quot;title&quot;&amp;gt;인터넷 익스플로러&amp;lt;/a&amp;gt; ... &amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예제에서는 a 태그중에 id가 link_axxx class가 title인 값을 보여주고 있습니다. 이 페이지에서 id가 link_axxx인 값은 위 태그말고는 없어야 합니다.(가끔 잘못 만드는 경우 있을 수 있습니다만 오동작할 가능성이 있습니다.) 반면, class가 title인 다른 태그들은 여럿이 있을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSS는 cascading style sheet의 줄임말로 HTML 파일에 스타일(화면에 어떻게 표시되어야 할지)을 제공해줍니다.&lt;br /&gt;이를 위해 CSS의 중요한 요소는 지금 크롤링을 위해 필요하지 않아 생략하고 크롤링에서 사용되는 요소는 CSS 선택자입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSS 선택자는 CSS가 HTML의 특정 태그 또는 태그들을 선택할 수 있도록 하는 CSS의 문법입니다.&lt;br /&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Selectors&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Selectors&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660178651271&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;CSS 선택자 - CSS: Cascading Style Sheets | MDN&quot; data-og-description=&quot;CSS 선택자는 CSS 규칙을 적용할 요소를 정의합니다.CSS 선택자는 CSS 규칙을 적용할 요소를 정의합니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Selectors&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Selectors&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bWWzfA/hyPoojOI8E/nTgfDomrekaqGb8Zh7ntd1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Selectors&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Selectors&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bWWzfA/hyPoojOI8E/nTgfDomrekaqGb8Zh7ntd1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;CSS 선택자 - CSS: Cascading Style Sheets | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CSS 선택자는 CSS 규칙을 적용할 요소를 정의합니다.CSS 선택자는 CSS 규칙을 적용할 요소를 정의합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 내용은 위 문서를 꼼꼼히 읽어보시길 추천드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;CSS 선택자 가운데 위에서 이야기한 id는 #을 붙여서, 클래스는 .을 붙이면 됩니다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;위 예제에서 #link_axxx 를 하거나 .title을 사용하면 위 a 태그가 선택될 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크롤링을 하려면 웹페이지가 HTML 태그들과 어트리뷰트들을 어떻게 쓰고 있는지 분석이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해 브라우저를 띄워서 인스펙터를 실행해보겠습니다.&lt;br /&gt;인스펙터는 크롬/웨일 기준 Ctrl + Shift + i 또는 F12를 누르시거나 메뉴에서 개발자도구를 선택하시면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;660&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z6WKV/btrJpeIrCMt/8JrnULlSwB0LQDj3Ihvn3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z6WKV/btrJpeIrCMt/8JrnULlSwB0LQDj3Ihvn3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z6WKV/btrJpeIrCMt/8JrnULlSwB0LQDj3Ihvn3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz6WKV%2FbtrJpeIrCMt%2F8JrnULlSwB0LQDj3Ihvn3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1010&quot; height=&quot;660&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;660&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스펙터의 이 버튼을 클릭하거나 Ctrl + Shift + C를 누르면 마우스가 이동하는 곳이 푸른색으로 변합니다.&lt;br /&gt;아무글이나 선택해보면 다음과 같이 변합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;958&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N4HTx/btrJqmsaLJA/UzwqXZY7NBwskW2XFA0O61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N4HTx/btrJqmsaLJA/UzwqXZY7NBwskW2XFA0O61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N4HTx/btrJqmsaLJA/UzwqXZY7NBwskW2XFA0O61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN4HTx%2FbtrJqmsaLJA%2FUzwqXZY7NBwskW2XFA0O61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;958&quot; height=&quot;535&quot; data-origin-width=&quot;958&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스펙터 창이 Elements라는 항목으로 바뀌면서 HTML 태그들이 트리 구조로 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대충 보면 이 페이지는 area-main이라는 클래스를 가진 div 태그 안에 area-common 클래스를 가진&amp;nbsp; div태그 안에 article이라는 태그들이 반복적으로 나타나는 것을 알 수 있습니다. (HTML tag 마지막을 보시거나 직접 실행해보세요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 코드의 9번줄에서는 beautiful soup의 select 함수에 .area-main &amp;gt; .area-common &amp;gt; article 라는 CSS 선택자를 전달해주었습니다.&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;A &amp;gt; B 는 CSS 선택자 가운데 A의 직접 자식들 중에서 B를 선택하도록 하는 선택자입니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과로 반환되는 articles는 여러개의 article 태그집합을 가르키고 있을 것입니다.&lt;br /&gt;article 내부를 보면 a 태그, article-content라는 클래스를 갖는 div 태그가 있고 그 div 태그 내에 title이라는 클래스를 갖는 strong태그가 제목을, summary 클래스를 갖는 p 태그가 요약을 가지고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for loop를 만들어 각각의 article 태그 집합을 순회하며 select_one 함수를 이용해 해당하는 값들을 꺼내 출력해주면 제목과 요약 정보들을 크롤링하는데 성공한 것을 볼 수 있습니다. (아래는 보기 좋게 하려고 제목만 출력했습니다.)&lt;/p&gt;
&lt;pre id=&quot;code_1660179514844&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;인터넷 익스플로러 종료 미리하기
[웨일] 모바일에서 전송한 url/사진 등이 PC에서 안보일때
chrome/whale등에서 파일 다운로드 안될때 확인
[초프만2022] 1. 안드로이드 스튜디오 설치하기
원격에서 듀얼부팅할때 순서 바꾸는 법
flutter 따라해보기 - 첫번째 앱 1
참조된 계정이 현재 잠겨있으므로 그 계정으로 로그온 할 수 없습니다
[C++] 소스코드에서 컴파일러 구분하기?
DART 대충 빠르게 훝어본 C++과 다른점
[C++11] std::enable_shared_from_this&lt;/code&gt;&lt;/pre&gt;</description>
      <category>개발</category>
      <category>BeautifulSoup</category>
      <category>크롤링예제</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/478</guid>
      <comments>https://bunhere.tistory.com/478#entry478comment</comments>
      <pubDate>Thu, 11 Aug 2022 09:59:37 +0900</pubDate>
    </item>
    <item>
      <title>인터넷 익스플로러 종료 미리하기</title>
      <link>https://bunhere.tistory.com/475</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;올해 6월부터 인터넷 익스플로러 사용이 종료됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MS에서 이걸 미리 적용할 수 있는 방법을 제공하고 있는 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.microsoft.com/ko-kr/deployedge/edge-ie-disable-ie11&quot;&gt;https://docs.microsoft.com/ko-kr/deployedge/edge-ie-disable-ie11&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1651453379693&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Internet Explorer 11 사용하지 않는 경우&quot; data-og-description=&quot;Internet Explorer 11을 사용하지 않도록 설정하고 Microsoft Edge에서 Internet Explorer 모드를 사용하는 방법을 알아봅니다.&quot; data-og-host=&quot;docs.microsoft.com&quot; data-og-source-url=&quot;https://docs.microsoft.com/ko-kr/deployedge/edge-ie-disable-ie11&quot; data-og-url=&quot;https://docs.microsoft.com/ko-kr/deployedge/edge-ie-disable-ie11&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/csCeGX/hyOe7hWUgt/fDEOLDDXGFumZFF8kduXo0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/4DuOa/hyOdwp6Ct4/lluahDzHNxqQ6X7TyYhNc0/img.png?width=600&amp;amp;height=227&amp;amp;face=0_0_600_227&quot;&gt;&lt;a href=&quot;https://docs.microsoft.com/ko-kr/deployedge/edge-ie-disable-ie11&quot; data-source-url=&quot;https://docs.microsoft.com/ko-kr/deployedge/edge-ie-disable-ie11&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/csCeGX/hyOe7hWUgt/fDEOLDDXGFumZFF8kduXo0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/4DuOa/hyOdwp6Ct4/lluahDzHNxqQ6X7TyYhNc0/img.png?width=600&amp;amp;height=227&amp;amp;face=0_0_600_227');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Internet Explorer 11 사용하지 않는 경우&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Internet Explorer 11을 사용하지 않도록 설정하고 Microsoft Edge에서 Internet Explorer 모드를 사용하는 방법을 알아봅니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.microsoft.com/download/details.aspx?id=103124&amp;amp;msclkid=eae4a72fb1fb11ecb97ca3096b36cc06&quot;&gt;https://www.microsoft.com/download/details.aspx?id=103124&amp;amp;msclkid=eae4a72fb1fb11ecb97ca3096b36cc06&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1651453379694&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Download  Administrative Templates (.admx) for Windows 10 May 2021 Update (21H1) from Official Microsoft Download Center&quot; data-og-description=&quot;Important! Selecting a language below will dynamically change the complete page content to that language. Download This page provides the complete set of Administrative Templates (.admx) for Windows 10 May 2021 Update (21H1) Details Administrative Template&quot; data-og-host=&quot;www.microsoft.com&quot; data-og-source-url=&quot;https://www.microsoft.com/download/details.aspx?id=103124&amp;amp;msclkid=eae4a72fb1fb11ecb97ca3096b36cc06&quot; data-og-url=&quot;https://www.microsoft.com/en-us/download/details.aspx?id=103124&amp;amp;msclkid=eae4a72fb1fb11ecb97ca3096b36cc06&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Y2FIh/hyOfbdBwLa/rkmr5y5MRAHXqZYq6F4sI0/img.jpg?width=2518&amp;amp;height=756&amp;amp;face=0_0_2518_756,https://scrap.kakaocdn.net/dn/H4WzR/hyOdyg9EPv/mFKTnFqwZaeq8OtlYvcrTk/img.png?width=1259&amp;amp;height=378&amp;amp;face=0_0_1259_378&quot;&gt;&lt;a href=&quot;https://www.microsoft.com/download/details.aspx?id=103124&amp;amp;msclkid=eae4a72fb1fb11ecb97ca3096b36cc06&quot; data-source-url=&quot;https://www.microsoft.com/download/details.aspx?id=103124&amp;amp;msclkid=eae4a72fb1fb11ecb97ca3096b36cc06&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Y2FIh/hyOfbdBwLa/rkmr5y5MRAHXqZYq6F4sI0/img.jpg?width=2518&amp;amp;height=756&amp;amp;face=0_0_2518_756,https://scrap.kakaocdn.net/dn/H4WzR/hyOdyg9EPv/mFKTnFqwZaeq8OtlYvcrTk/img.png?width=1259&amp;amp;height=378&amp;amp;face=0_0_1259_378');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Download Administrative Templates (.admx) for Windows 10 May 2021 Update (21H1) from Official Microsoft Download Center&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Important! Selecting a language below will dynamically change the complete page content to that language. Download This page provides the complete set of Administrative Templates (.admx) for Windows 10 May 2021 Update (21H1) Details Administrative Template&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 여기서 윈도우즈10 관리 템플릿을 받아 설치합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 윈도우즈 버튼을 누르고 &quot;그룹정책편집&quot; 을 검색하여 실행합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsoklm/btrAYvwVzqY/FTMFfKgkpm6sd6q37jYi01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsoklm/btrAYvwVzqY/FTMFfKgkpm6sd6q37jYi01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsoklm/btrAYvwVzqY/FTMFfKgkpm6sd6q37jYi01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbsoklm%2FbtrAYvwVzqY%2FFTMFfKgkpm6sd6q37jYi01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;365&quot; height=&quot;270&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 컴퓨터 구성 &amp;gt; 관리 템플릿 &amp;gt; Internet Explorer 를 선택합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Internet Explorer 11을 독립 실행형 브라우저로 사용 안함 을 사용합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2kpSr/btrAVshoXZP/HsPSlPrytsLPWnf4A0T7ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2kpSr/btrAVshoXZP/HsPSlPrytsLPWnf4A0T7ik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2kpSr/btrAVshoXZP/HsPSlPrytsLPWnf4A0T7ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2kpSr%2FbtrAVshoXZP%2FHsPSlPrytsLPWnf4A0T7ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1076&quot; height=&quot;144&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Internet Explorer가 edge만 실행되는 것을 확인할 수 있습니다.&lt;/p&gt;</description>
      <category>IE굿바이</category>
      <category>IE종료대응</category>
      <category>IE종료미리해보기</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/475</guid>
      <comments>https://bunhere.tistory.com/475#entry475comment</comments>
      <pubDate>Mon, 2 May 2022 11:04:33 +0900</pubDate>
    </item>
    <item>
      <title>[웨일] 모바일에서 전송한 url/사진 등이 PC에서 안보일때</title>
      <link>https://bunhere.tistory.com/472</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;웨일이나 네이버앱을 사용하면 공유기능에 &quot;PC로 보내기&quot; 또는 &quot;웨일로 보내기&quot; 기능이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 좋아하는 기능인데, 가끔 전송이 안될떄가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 해당 PC의 whale://sync-internals/ 에 들어가 본다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cALfcI/btrwixmr2By/WVd7VEq6egVakwY86yaltk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cALfcI/btrwixmr2By/WVd7VEq6egVakwY86yaltk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cALfcI/btrwixmr2By/WVd7VEq6egVakwY86yaltk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcALfcI%2Fbtrwixmr2By%2FWVd7VEq6egVakwY86yaltk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1257&quot; height=&quot;179&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오른쪽에 Trigger GetUpdates를 누르면 전송되는 것을 볼 수 있다.&amp;nbsp;&lt;/p&gt;</description>
      <category>컴퓨터 사용 팁</category>
      <category>웨일PC로보내기</category>
      <category>웨일버그</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/472</guid>
      <comments>https://bunhere.tistory.com/472#entry472comment</comments>
      <pubDate>Fri, 18 Mar 2022 14:17:35 +0900</pubDate>
    </item>
    <item>
      <title>chrome/whale등에서 파일 다운로드 안될때 확인</title>
      <link>https://bunhere.tistory.com/471</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;갑자기 파일 다운로드가 안되는데 원인을 알 수가 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 histograms을 봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;( chrome://histograms 또는 whale://histograms )&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;107&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbKT0N/btrsYceURt1/OgXfUUlWQ0WRbAMgjL4Lqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbKT0N/btrsYceURt1/OgXfUUlWQ0WRbAMgjL4Lqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbKT0N/btrsYceURt1/OgXfUUlWQ0WRbAMgjL4Lqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbKT0N%2FbtrsYceURt1%2FOgXfUUlWQ0WRbAMgjL4Lqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;751&quot; height=&quot;107&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;107&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 아래 사이트에 들어가서 저 문자열 (&lt;span style=&quot;background-color: #f5f5f5; color: #000000;&quot;&gt;Download.CancelReason&lt;/span&gt;)을 검색한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://source.chromium.org/chromium&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://source.chromium.org/chromium&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjTo4O/btrsXsPS8Z2/pEMMZKZYOBa4VibrySWzo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjTo4O/btrsXsPS8Z2/pEMMZKZYOBa4VibrySWzo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjTo4O/btrsXsPS8Z2/pEMMZKZYOBa4VibrySWzo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjTo4O%2FbtrsXsPS8Z2%2FpEMMZKZYOBa4VibrySWzo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;698&quot; height=&quot;332&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;332&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫번째를 보면 객체가 DownloadCancelReason. DownloadCancelReason으로 다시 검색을 해야 나올것 같으니 다시 검색하면 아래와 같은 enum이 나온다.&lt;/p&gt;
&lt;pre id=&quot;code_1644475151373&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;enum class DownloadCancelReason {
  // Existed download path after download target determination.
  kExistingDownloadPath = 0,
  // Canceled due to download target determiner confirmation result.
  kTargetConfirmationResult = 1,
  // Canceled due to no valid virtual path.
  kNoValidPath = 2,
  // Canceled due to no mixed content.
  kMixedContent = 3,
  // Canceled due to failed path reservacation.
  kFailedPathReservation = 4,
  // Canceled due to empty local path.
  kEmptyLocalPath = 5,
  kMaxValue = kEmptyLocalPath
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3은 MixedContent라 Cancel되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 url 복사해서 붙이니 다운로드가 되었다. ;&lt;/p&gt;</description>
      <category>컴퓨터 사용 팁</category>
      <category>다운로드에러</category>
      <category>크로미움코드검색</category>
      <category>히스토그램사용법</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/471</guid>
      <comments>https://bunhere.tistory.com/471#entry471comment</comments>
      <pubDate>Thu, 10 Feb 2022 15:40:26 +0900</pubDate>
    </item>
    <item>
      <title>원격에서 듀얼부팅할때 순서 바꾸는 법</title>
      <link>https://bunhere.tistory.com/469</link>
      <description>&lt;pre id=&quot;code_1631581723099&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash
sudo grub-reboot 2
sudo reboot&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 윈도우즈, 리눅스 멀티부팅을 하면 리눅스가 1번, 윈도우즈가 3번이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 이용해 리눅스에서 윈도우즈로 부팅이 가능할것 같다.&lt;br /&gt;나는 16.04 쓰는데 위에 걸로 문제가 없었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시 안되면 아래 방법도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://webnautes.tistory.com/512&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://webnautes.tistory.com/512&lt;/a&gt; 에 더 자세한 정보가 있네.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- /etc/default/grub 에서 GROUP_DEFAULT=saved로 수정&lt;br /&gt;- sudo grub-set-default 2&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버전마다 다를 수 있을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;16.04 이상은 이걸 써야 할듯&lt;/p&gt;</description>
      <category>컴퓨터 사용 팁</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/469</guid>
      <comments>https://bunhere.tistory.com/469#entry469comment</comments>
      <pubDate>Tue, 14 Sep 2021 10:09:44 +0900</pubDate>
    </item>
    <item>
      <title>flutter 따라해보기 - 첫번째 앱 1</title>
      <link>https://bunhere.tistory.com/467</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;설치하는&amp;nbsp;법&amp;nbsp;:&amp;nbsp;&lt;a href=&quot;https://flutter.dev/docs/get-started/install&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://flutter.dev/docs/get-started/install&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라하는 글 : &lt;a href=&quot;https://flutter.dev/docs/get-started/codelab#step-1-create-the-starter-flutter-app&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://flutter.dev/docs/get-started/codelab#step-1-create-the-starter-flutter-app&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://flutter.dev/docs/get-started/test-drive#create-app&quot;&gt;https://flutter.dev/docs/get-started/test-drive#create-app&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 따라 앱을 그냥 만들고 커밋 (&lt;a href=&quot;https://github.com/bunhere/study/commit/2881e3a5e538a162f41e032a77db23cb64fab019&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/bunhere/study/commit/2881e3a5e538a162f41e032a77db23cb64fab019&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;534&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dc6tQy/btq5Q53no19/IiCIQce5FgNci2uSB5XWDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dc6tQy/btq5Q53no19/IiCIQce5FgNci2uSB5XWDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dc6tQy/btq5Q53no19/IiCIQce5FgNci2uSB5XWDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdc6tQy%2Fbtq5Q53no19%2FIiCIQce5FgNci2uSB5XWDk%2Fimg.png&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;534&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;lib/main.dar가 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 코드로 변경하고 웹으로 실행&lt;/p&gt;
&lt;pre id=&quot;code_1622040720333&quot; class=&quot;java&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';

void main() =&amp;gt; runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;81&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxegpC/btq5M4q6dzS/YSj8u9fXTQRqDUXhD5rCW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxegpC/btq5M4q6dzS/YSj8u9fXTQRqDUXhD5rCW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxegpC/btq5M4q6dzS/YSj8u9fXTQRqDUXhD5rCW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxegpC%2Fbtq5M4q6dzS%2FYSj8u9fXTQRqDUXhD5rCW0%2Fimg.png&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;81&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;522&quot; data-origin-height=&quot;631&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9MnvP/btq5NGDyOqb/s5r8MPSSUcebUcdqjhH5sK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9MnvP/btq5NGDyOqb/s5r8MPSSUcebUcdqjhH5sK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9MnvP/btq5NGDyOqb/s5r8MPSSUcebUcdqjhH5sK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9MnvP%2Fbtq5NGDyOqb%2Fs5r8MPSSUcebUcdqjhH5sK%2Fimg.png&quot; data-origin-width=&quot;522&quot; data-origin-height=&quot;631&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리(Observations)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Material 앱이란다. 플러터는 메테리얼위젯을 제공한다. 어쩌구. uses-material-design: true in flutter section of pubspec.yaml (false로 바꿔봤는데 딱히 아직 차이를 모르겠다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;306&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l8vie/btq5SdfpT5m/oLeAMPvfOMGM5SZdery2c0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l8vie/btq5SdfpT5m/oLeAMPvfOMGM5SZdery2c0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l8vie/btq5SdfpT5m/oLeAMPvfOMGM5SZdery2c0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl8vie%2Fbtq5SdfpT5m%2FoLeAMPvfOMGM5SZdery2c0%2Fimg.png&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;306&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* main() 은 화살표(=&amp;gt;) 노테이션을 쓴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 앱은 StatelessWidget을 extends한다. 앱 자체를 위젯으로 만든다. 플러터에서 거의 모든것이 widget이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Scaffold 위젯은 appBar와 body를 갖고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 위젯의 중요한것은 build()를 제공하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* body는 Text 위젯을 갖는 Center 위젯으로 이뤄져있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 하고 실행하면 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;630&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qSTqc/btq5R0HgVH0/J4MbMAzB2wmf34YNzV1TR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qSTqc/btq5R0HgVH0/J4MbMAzB2wmf34YNzV1TR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qSTqc/btq5R0HgVH0/J4MbMAzB2wmf34YNzV1TR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqSTqc%2Fbtq5R0HgVH0%2FJ4MbMAzB2wmf34YNzV1TR0%2Fimg.png&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;630&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/bunhere/study/commit/8a1fae4ccf055fdf2b8562973bffb00714f5f373&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/bunhere/study/commit/8a1fae4ccf055fdf2b8562973bffb00714f5f373&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;Step 2 부분&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pubspec.yaml 은 dependency등을 관리하는 파일인가보다.&lt;/p&gt;
&lt;pre id=&quot;code_1622121182016&quot; class=&quot;java&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  english_words: ^4.0.0-0
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;english_words 를 추가하고 나면 상단에 이런 게 생긴다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1363&quot; data-origin-height=&quot;108&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DASI0/btq5W9YJav8/FOF6V3rhTtRriI3fTS1gf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DASI0/btq5W9YJav8/FOF6V3rhTtRriI3fTS1gf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DASI0/btq5W9YJav8/FOF6V3rhTtRriI3fTS1gf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDASI0%2Fbtq5W9YJav8%2FFOF6V3rhTtRriI3fTS1gf0%2Fimg.png&quot; data-origin-width=&quot;1363&quot; data-origin-height=&quot;108&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pub get을 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제대로 가져왔으면 pubspec.lock파일에 english_words가 아래처럼 자동 생성되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;245&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mjA6J/btq5YqFGYbU/ZMly4d9A5bz3gPydceLh2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mjA6J/btq5YqFGYbU/ZMly4d9A5bz3gPydceLh2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mjA6J/btq5YqFGYbU/ZMly4d9A5bz3gPydceLh2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmjA6J%2Fbtq5YqFGYbU%2FZMly4d9A5bz3gPydceLh2k%2Fimg.png&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;245&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래처럼 코딩한다.&lt;/p&gt;
&lt;pre id=&quot;code_1622121318136&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;diff --git a/project/flutter/hello/lib/main.dart b/project/flutter/hello/lib/main.dart
index 349bf01..0eafe0a 100644
--- a/project/flutter/hello/lib/main.dart
+++ b/project/flutter/hello/lib/main.dart
@@ -4,12 +4,14 @@
 // found in the LICENSE file.
 
 import 'package:flutter/material.dart';
+import 'package:english_words/english_words.dart';
 
 void main() =&amp;gt; runApp(MyApp());
 
 class MyApp extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
+    final wordPair = WordPair.random();
     return MaterialApp(
       title: 'Welcome to Flutter',
       home: Scaffold(
@@ -17,7 +19,7 @@ class MyApp extends StatelessWidget {
           title: Text('Welcome to Flutter'),
         ),
         body: Center(
-          child: Text('Hello World'),
+          child: Text(wordPair.asPascalCase),
         ),
       ),
     );&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래처럼 나온다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;507&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cd0yTv/btq5TskvWBv/UHo2S547zBzB5nEbcjsuoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cd0yTv/btq5TskvWBv/UHo2S547zBzB5nEbcjsuoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cd0yTv/btq5TskvWBv/UHo2S547zBzB5nEbcjsuoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcd0yTv%2Fbtq5TskvWBv%2FUHo2S547zBzB5nEbcjsuoK%2Fimg.png&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;507&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Step 3 Stateful widget 추가하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stateful widget과 Stateless widget으로 개념을 나눠둔거 정말 좋은 생각인것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stateful widget 은 lifetime동안 바뀔 수 있는 상태를 관리한다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 Stateful widget은 State를 갖고 있다. Stateful widget 자체는 Stateless widget처럼 immutable 하고 버려지고 다시 만들어진다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면, State는 Widget의 수명에 걸쳐 유지된다고 하는데, 이 위젯이 자신을 가진 Stateful widget을 말하는건가? Stateful widget은 버려질 수 있다고 했는데 흠.. 아직 잘 모르겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제대로 RandowWords 라는 Stateful widget, _RandomWordsState라는 State를 만들자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신기한게 제일 밑에다가 stful 입력하고 엔터치면 보일러플레이트 코드를 자동으로 완성해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원글에는 따로 언급이 없는데 아래같은 코드가 생성되는데 그 중에 key 를 인자로 하는 생성자가 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1622122322175&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@@ -19,9 +18,24 @@ class MyApp extends StatelessWidget {
           title: Text('Welcome to Flutter'),
         ),
         body: Center(
-          child: Text(wordPair.asPascalCase),
+          child: RandomWords(),
         ),
       ),
     );
   }
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1622122221600&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class RandomWords extends StatefulWidget {
  const RandomWords({Key key}) : super(key: key);

  @override
  _RandomWordsState createState() =&amp;gt; _RandomWordsState();
}

class _RandomWordsState extends State&amp;lt;RandomWords&amp;gt; {
  @override
  Widget build(BuildContext context) {
    final wordPair = WordPair.random();
    return Text(wordPair.asPascalCase);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MyApp의 Scaffold에 RandomWords로 했으니 이 생성자의 key는 에러가 난다. 어떻게 고칠지 아직 모르니 그냥 삭제했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직은 State가 뭘하는 것인지 모르겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발</category>
      <category>1일30분공부</category>
      <category>Flutter</category>
      <category>플러터</category>
      <category>플러터튜토리얼따라하기</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/467</guid>
      <comments>https://bunhere.tistory.com/467#entry467comment</comments>
      <pubDate>Thu, 27 May 2021 00:11:14 +0900</pubDate>
    </item>
    <item>
      <title>참조된 계정이 현재 잠겨있으므로 그 계정으로 로그온 할 수 없습니다</title>
      <link>https://bunhere.tistory.com/466</link>
      <description>&lt;p&gt;요약: 네트워크를 통해 로그인 시도가 있었고 NLTM 보안레벨 올리고, 공격들어오는 계정명을 바꿔버림&amp;nbsp;&lt;/p&gt;
&lt;p&gt;추가로 windows 10 방화벽에서 원격데스크톱도 꺼버림&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;빌드를 걸어놓고 왔을 뿐인데, 로그인이 안되고 위와 같은 메시지가 뜬다.&lt;/p&gt;
&lt;p&gt;리부팅을 해도 똑같음.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 에러가 나는 이유는 비밀번호를 틀렸기 때문이나, 나는 로그인을 한 적이 없다.&lt;/p&gt;
&lt;p&gt;그래서 이벤트 뷰어를 살펴봤다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpez95/btq26ppGaOn/PNAwUT8KKMy2yOpAO7bZB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpez95/btq26ppGaOn/PNAwUT8KKMy2yOpAO7bZB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpez95/btq26ppGaOn/PNAwUT8KKMy2yOpAO7bZB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbpez95%2Fbtq26ppGaOn%2FPNAwUT8KKMy2yOpAO7bZB1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDAHoH/btq26FeIk0M/kqinIk5EMaDUX1wuZFzKLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDAHoH/btq26FeIk0M/kqinIk5EMaDUX1wuZFzKLK/img.png&quot; data-alt=&quot;이벤트 뷰어&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDAHoH/btq26FeIk0M/kqinIk5EMaDUX1wuZFzKLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDAHoH%2Fbtq26FeIk0M%2FkqinIk5EMaDUX1wuZFzKLK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이벤트 뷰어&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;무수히 많은 로그인 실패 에러가 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRWJXv/btq22aNNpqN/dkPcR5ePE4jl5tzOkVbg3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRWJXv/btq22aNNpqN/dkPcR5ePE4jl5tzOkVbg3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRWJXv/btq22aNNpqN/dkPcR5ePE4jl5tzOkVbg3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRWJXv%2Fbtq22aNNpqN%2FdkPcR5ePE4jl5tzOkVbg3k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bY1EIi/btq26n6tB4K/eR5DTOchILmAqkP7hJgt81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bY1EIi/btq26n6tB4K/eR5DTOchILmAqkP7hJgt81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bY1EIi/btq26n6tB4K/eR5DTOchILmAqkP7hJgt81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbY1EIi%2Fbtq26n6tB4K%2FeR5DTOchILmAqkP7hJgt81%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;ADMINISTRATOR 계정으로 NLTM으로 공격이 들어온다.&lt;/p&gt;
&lt;p&gt;일단 NLTM을 검색해봤더니 보안레벨을 올리는게 있어서 올려봤으나 공격은 계속 들어오네&lt;/p&gt;
&lt;p&gt;* NLTM을 끄는 법&lt;/p&gt;
&lt;p&gt;실행(windows키+R)을 통해 &lt;a href=&quot;http://gpedit.msc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;gpedit.msc&lt;/a&gt;를 실행&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/svPRd/btq21MsYvVj/vCwMKESe1UzfJEOVFOa2Ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/svPRd/btq21MsYvVj/vCwMKESe1UzfJEOVFOa2Ok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/svPRd/btq21MsYvVj/vCwMKESe1UzfJEOVFOa2Ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsvPRd%2Fbtq21MsYvVj%2FvCwMKESe1UzfJEOVFOa2Ok%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKvTQG/btq23uFfZiq/GI0KdwfcK0aqiI2Q7zKYyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKvTQG/btq23uFfZiq/GI0KdwfcK0aqiI2Q7zKYyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKvTQG/btq23uFfZiq/GI0KdwfcK0aqiI2Q7zKYyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKvTQG%2Fbtq23uFfZiq%2FGI0KdwfcK0aqiI2Q7zKYyK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;여전히 들어온다.&lt;/p&gt;
&lt;p&gt;그래서 아예 Administrator 계정이름을 내 마음대로 바꿔버림 (같은 위치에 Administrator 계정 이름 바꾸기)&lt;/p&gt;
&lt;p&gt;그래도 들어오긴 한다.&lt;/p&gt;
&lt;p&gt;추가로 일단 Windows 원격 데스크톱도 끄기로 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b27Syq/btq26D86scM/p8g9BNoQkXnRXlcN7pSOo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b27Syq/btq26D86scM/p8g9BNoQkXnRXlcN7pSOo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b27Syq/btq26D86scM/p8g9BNoQkXnRXlcN7pSOo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb27Syq%2Fbtq26D86scM%2Fp8g9BNoQkXnRXlcN7pSOo1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;방화벽 및 네트워크 보호 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6mjUN/btq21B5XbbF/Zh6JnEUfoFkZFWs4tf6xT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6mjUN/btq21B5XbbF/Zh6JnEUfoFkZFWs4tf6xT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6mjUN/btq21B5XbbF/Zh6JnEUfoFkZFWs4tf6xT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6mjUN%2Fbtq21B5XbbF%2FZh6JnEUfoFkZFWs4tf6xT1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;방화벽에서 앱 허용 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhOP9G/btq27YkAs4Q/CVAAg5SvzfU6motIb9GhF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhOP9G/btq27YkAs4Q/CVAAg5SvzfU6motIb9GhF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhOP9G/btq27YkAs4Q/CVAAg5SvzfU6motIb9GhF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhOP9G%2Fbtq27YkAs4Q%2FCVAAg5SvzfU6motIb9GhF1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;원격 데스크톱을 꺼버림&lt;/p&gt;
&lt;p&gt;더이상 공격이 안들어옴&lt;/p&gt;</description>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/466</guid>
      <comments>https://bunhere.tistory.com/466#entry466comment</comments>
      <pubDate>Tue, 20 Apr 2021 19:18:08 +0900</pubDate>
    </item>
    <item>
      <title>[C++] 소스코드에서 컴파일러 구분하기?</title>
      <link>https://bunhere.tistory.com/463</link>
      <description>&lt;p&gt;원본 : &lt;a href=&quot;https://quuxplusone.github.io/blog/2021/01/13/conversion-operator-lookup/&quot;&gt;https://quuxplusone.github.io/blog/2021/01/13/conversion-operator-lookup/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;친구의 페이스북에 올라온 C++ 컴파일러 구분하기 란 글을 보았다.&lt;br&gt;역시 난 C++을 모르는듯 ㅎㅎ&lt;/p&gt;
&lt;p&gt;여기서 핵심은 U 와 T가 무엇으로 lookup되어야 하는지를 정하는게 표준에 있는데&lt;br&gt;컴파일러가 제멋대로 구현했다는 것 같다.&lt;/p&gt;
&lt;p&gt;U, T 모두에 대해서 gcc만 제대로 A scope으로 룩업한다고...&lt;/p&gt;
&lt;p&gt;code link : &lt;a href=&quot;https://godbolt.org/z/jo3dc4&quot;&gt;https://godbolt.org/z/jo3dc4&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c++&quot;&gt;struct T1 {}; struct T2 {};
struct U1 {}; struct U2 {};

struct A {
    using T = T1;
    using U = U1;
    operator U1 T1::*();
    operator U1 T2::*();
    operator U2 T1::*();
    operator U2 T2::*();
};

inline auto which(U1 T1::*) { return &amp;quot;gcc&amp;quot;; }
inline auto which(U1 T2::*) { return &amp;quot;icc&amp;quot;; }
inline auto which(U2 T1::*) { return &amp;quot;msvc&amp;quot;; }
inline auto which(U2 T2::*) { return &amp;quot;clang&amp;quot;; }

int main() {
    A a;
    using T = T2;
    using U = U2;
    puts(which(a.operator U T::*()));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C++ 문법을 한번 봐야겠다는 생각이 드네&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/463</guid>
      <comments>https://bunhere.tistory.com/463#entry463comment</comments>
      <pubDate>Tue, 19 Jan 2021 21:56:58 +0900</pubDate>
    </item>
    <item>
      <title>DART 대충 빠르게 훝어본 C++과 다른점</title>
      <link>https://bunhere.tistory.com/462</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;타입&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;num 타입 : int 타입 + double 타입인듯&lt;br /&gt;float은 안보임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;auto 같은 var&lt;br /&gt;as 로 타입변환이 되는데 0.1이 int가 되진 못함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입검사&lt;br /&gt;if (a is int) {...}&lt;br /&gt;if (a is! int) {...}&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;연산자 &lt;a href=&quot;https://dart.dev/guides/language/language-tour#operators&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dart.dev/guides/language/language-tour#operators&lt;/a&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;~/ : 몫 연산자가 있음 아무래도 int 타입때문인듯&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- null aware operators&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;?? : if null operator : null인지 체크&lt;/p&gt;
&lt;pre id=&quot;code_1637241107609&quot; class=&quot;c++ arduino&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// prefs.getBool('some-feature') 가 null이면 false 아니면 prefs.getBool('some-feature')
bool v = prefs.getBool('some-feature') ?? false;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;??=&amp;nbsp; null aware assignment&lt;br /&gt;?. null aware access&lt;br /&gt;?... null aware spread operator [ Dart 2.3부터 ]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;as, is, is! :&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;함수&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;print('hello ${person.name}')&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;함수의 선택 매개변수, 기본값&lt;br /&gt;void something(String name, {int age = 10}) {}&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;클래스&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;class의 private은 _으로 시작&lt;/li&gt;
&lt;li&gt;getter setter&lt;br /&gt;int get age =&amp;gt; _age;&lt;br /&gt;set age =&amp;gt; _age;&lt;/li&gt;
&lt;li&gt;상속은 extends, abstract class는 implements, 상속하지 않고 가져오는 with&lt;/li&gt;
&lt;li&gt;오버라이드할때 메소드앞에는 @override&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PS, 더 있을 수 있습니다.&lt;/p&gt;</description>
      <category>프로그래밍 언어</category>
      <category>dart #flutter공부</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/462</guid>
      <comments>https://bunhere.tistory.com/462#entry462comment</comments>
      <pubDate>Tue, 19 Jan 2021 07:53:42 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] std::enable_shared_from_this</title>
      <link>https://bunhere.tistory.com/460</link>
      <description>&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;std::shared_ptr은 std::unique_ptr과 함께 C++11부터 사용 가능한 smart pointer 이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;code style=&quot;font-size: 12.8px; font-family: DejaVuSansMono, &amp;quot;DejaVu Sans Mono&amp;quot;, courier, monospace !important;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;std::shared_ptr&lt;/span&gt;&lt;/code&gt;&lt;span style=&quot;font-family: DejaVuSans, &amp;quot;DejaVu Sans&amp;quot;, arial, sans-serif; font-size: 12.8px;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;&amp;nbsp;is a smart pointer that retains shared ownership of an object through a pointer.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;font face=&quot;DejaVuSans, DejaVu Sans, arial, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;http://en.cppreference.com/w/cpp/memory/shared_ptr)&lt;/span&gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;std::unique_ptr과 다른점은 ownership을 공유(shared)한다는 점이다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;std::shared_ptr 객체를 만들때 한가지 문제가 되는 부분이 있는데, 아래와 같은 상황이 발생하지 않도록 주의해야 한다는 점이다.&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;Bad* p = new Bad;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;std::shared_ptr&amp;lt;Bad&amp;gt; a1(p);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;std::shared_ptr&amp;lt;Bad&amp;gt; a2(p); // ERROR! you may want to write std::shared_ptr&amp;lt;Bad&amp;gt; a2&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;a1&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;a1과 a2는 (같은 raw pointer p를 갖는) 서로 다른&amp;nbsp;&amp;nbsp;스마트 포인터이기 때문에 위 코드는 런타임에 아래처럼 죽게 된다. (mac&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures; font-family: Gulim, 굴림; font-size: 12pt;&quot;&gt;clang-900.0.39.2)&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;




&lt;/span&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #000000; background-color: #ffffff}
span.s1 {font-variant-ligatures: no-common-ligatures}
&lt;/span&gt;&lt;/style&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;


&lt;/span&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;




&lt;/span&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #000000; background-color: #ffffff}
span.s1 {font-variant-ligatures: no-common-ligatures}
&lt;/span&gt;&lt;/style&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;


&lt;/span&gt;&lt;p class=&quot;p1&quot;&gt;&lt;span class=&quot;s1&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;./a.out&lt;/span&gt;&lt;span class=&quot;Apple-converted-space&quot; style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;
&lt;/span&gt;&lt;p class=&quot;p1&quot;&gt;&lt;span class=&quot;s1&quot; style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;a.out(16448,0x7fff8e2d2340) malloc: *** error for object 0x7fc73b400340: pointer being freed was not allocated&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;
&lt;/span&gt;&lt;p class=&quot;p1&quot;&gt;&lt;span class=&quot;s1&quot; style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;*** set a breakpoint in malloc_error_break to debug&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures; font-family: Gulim, 굴림; font-size: 12pt;&quot;&gt;Abort trap: 6&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;우리가 raw pointer 를 아예 안쓰면 모르지만, 아래와 같은 경우는 난감하다.&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;void func(BadOrGood* p) {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;&amp;nbsp; std::shared_ptr&amp;lt;BadOrGood&amp;gt; a(p);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;&amp;nbsp; ...&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;T 를 구현할 때 std::enable_shared_from_this&amp;lt;T&amp;gt; 를 상속하면 T의 객체가 자신의&amp;nbsp;shared_ptr 객체를 알 수 있게 해준다.&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;class Good : public std::enable_shared_from_this&amp;lt;Good&amp;gt; { ... };&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;std::shared_ptr&amp;lt;Good&amp;gt; a(p.shared_from_this());&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;이렇게 enable_shared_from_this 를 상속받고, shared_ptr에 raw pointer를 넣을때는 shared_from_this() 를 통해 shared_ptr을 얻어서 호출하면 안전하다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;사실 아직 문제가 있는데&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;shared_ptr 객체를 만들지 않고 &amp;nbsp;shared_from_this()를 호출하면 std::bad_weak_ptr exception이 발생한다.(C++17부터, 그전에는 undefined behavior)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;그리고, 여전히 첫번째 예제(Bad)처럼 실수하면 죽는다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;이를 막기 위해서,&amp;nbsp;직접 new 를 못하게 막아 두고 shared_ptr 객체가 생성되도록 해야 한다.&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;class Good : public std::enable_shared_from_this&amp;lt;Good&amp;gt; {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;public:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;&amp;nbsp; std::shared_ptr&amp;lt;Good&amp;gt; create() { return std::make_shared&amp;lt;Good&amp;gt;();};&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;private:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;&amp;nbsp; Good() = default;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gulim, 굴림;&quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/460</guid>
      <comments>https://bunhere.tistory.com/460#entry460comment</comments>
      <pubDate>Tue, 6 Feb 2018 11:01:51 +0900</pubDate>
    </item>
    <item>
      <title>[GIT] windows에서 invalid username (wincred)</title>
      <link>https://bunhere.tistory.com/452</link>
      <description>&lt;p&gt;http://www.codewrecks.com/blog/index.php/2015/06/23/git-for-windows-getting-invalid-username-or-password-with-wincred/&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;만약 login이 귀찮아 wincred를 아래처럼 설정해서 썼다면, 비밀번호가 바뀌었을때 대략 난감해진다.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash plain&quot;&gt;git config --global credential.helper wincred&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이 상황에서는 제어판의 &quot;자격 증명 관리자&quot; 를 찾아 들어가 관련 repository와 관련된 것을 지워주고 다시 git 명령을 치면 된다.&lt;br /&gt;&lt;/p&gt;</description>
      <category>개발</category>
      <category>Git</category>
      <category>GitHub</category>
      <category>invalid username</category>
      <category>wincred</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/452</guid>
      <comments>https://bunhere.tistory.com/452#entry452comment</comments>
      <pubDate>Tue, 18 Oct 2016 20:52:13 +0900</pubDate>
    </item>
    <item>
      <title>[읽은 글] const correctness</title>
      <link>https://bunhere.tistory.com/451</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://herbsutter.com/2013/05/24/gotw-6a-const-correctness-part-1-3/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://herbsutter.com/2013/05/24/gotw-6a-const-correctness-part-1-3/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://herbsutter.com/2013/05/24/gotw-6b-const-correctness-part-2/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://herbsutter.com/2013/05/24/gotw-6b-const-correctness-part-2/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://herbsutter.com/2013/05/28/gotw-6b-solution-const-correctness-part-2/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://herbsutter.com/2013/05/28/gotw-6b-solution-const-correctness-part-2/&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;* 번역이 아니라 이해하고 정리한 내용입니다. 따라서 원 글의 의도가 전달되지 않을 수 있으며, 수정 될 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[ ] &lt;a href=&quot;https://herbsutter.com/2013/05/24/gotw-6a-const-correctness-part-1-3/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://herbsutter.com/2013/05/24/gotw-6a-const-correctness-part-1-3/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;1. shared variable&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Shared variable이란 하나 이상의 thread에서 동시에 접근할 수 있는 변수를 말한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;2. shared variable의 관점에서 const 나 mutable이란?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;const member function은 다음 두가지 중 하나를 반드시 만족해야 한다. (절대 공유되지 않는다는 가정이 있지 않는 한)&lt;/p&gt;&lt;p&gt;&amp;nbsp;- 진짜로 const(truly physically/bitwise const). 다시 말해 객체의 어떤 데이터에도 write하지 않아야 한다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;- 내부적으로 동기화되어서 (예를 들어 mutex, atomic&amp;lt;&amp;gt; 등으로) 동시에 호출되더라도 문제가 없어야 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;비슷하게, 멤버 변수에 mutable 키워드를 쓴다는 것은 그 변수가 쓸 쑤 있지만 논리적으로는 const(writable but logically const) 임을 의미한다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;- 논리적으로 const란 여러 동시성 (const) 연산들로부터 안전하다는 의미이다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;- mutable이 붙어있다는 것은 어떤 const operation이 사실은 write할지 모른다는 뜻이고, 동시성을 갖고 읽고 쓰는데 문제가 없다는 의미이다. 따라서 mutex 나 유사한 동기화 로직 아니면 atomic&amp;lt;&amp;gt;으로 만들어야 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;따라서, mutex 와 mutable 을 같이 써야 한다. (또는 atomic&amp;lt;&amp;gt; 과 mutable)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;3. c++98과 c++11에서 mutable과 const는 뭐가 다른가?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;먼저 그전에...&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 내용을 정리하기 전에, const와 mutable에 대해 헷갈리게 했던 부분은 const_cast를 통해 수정하면 되지 왜 mutable을 써야 하지? 하는 점이었다.&lt;/p&gt;&lt;p&gt;예를 들면 아래 처럼...&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;lang-cpp prettyprint prettyprinted&quot; style=&quot;margin-top: 0px; margin-bottom: 1em; padding: 5px; border: 0px; width: auto; max-height: 600px; overflow: auto; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; color: rgb(57, 51, 24); word-wrap: normal; background-color: rgb(239, 240, 241);&quot;&gt;&lt;code style=&quot;margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; white-space: inherit;&quot;&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;#include &amp;lt;vector&amp;gt;&lt;br /&gt;&lt;br /&gt;class Tile { ... };&lt;br /&gt;&lt;br /&gt;class TileStore {&lt;br /&gt; public:&lt;br /&gt;  Tile* getTile() const {&lt;br /&gt;    if (empty_tiles_.empty()) {&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;const_cast&amp;lt;TileStore*&amp;gt;(this)&lt;/span&gt;-&amp;gt;ReserveMoreTiles();&lt;br /&gt;    }&lt;br /&gt;    // ...&lt;br /&gt;    return //something;&lt;br /&gt; &amp;nbsp;}&lt;br /&gt;  void ReserveMoreTiles() {&lt;br /&gt;    // ...&lt;br /&gt;  }&lt;br /&gt; private:&lt;br /&gt;  std::vector&amp;lt;Tile*&amp;gt; empty_tiles_;&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;com&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(133, 140, 147);&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;먼저 아래 링크을 가져왔다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://stackoverflow.com/questions/11457953/const-cast-vs-mutable-any-difference&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://stackoverflow.com/questions/11457953/const-cast-vs-mutable-any-difference&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;const_cast는 사실 대상 객체의 const 속성을&amp;nbsp;제거하는 것이 아니다. 대신 접근 경로(access path)상에 const 속성을 바꿔주는 것이다.&lt;/p&gt;&lt;p&gt;따라서 진짜 const 객체에 대하여 const_cast를 수행하는 것은 Undefined behavior를 야기할 수 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;lang-cpp prettyprint prettyprinted&quot; style=&quot;margin-top: 0px; margin-bottom: 1em; padding: 5px; border: 0px; width: auto; max-height: 600px; overflow: auto; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; color: rgb(57, 51, 24); word-wrap: normal; background-color: rgb(239, 240, 241);&quot;&gt;&lt;code style=&quot;margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; white-space: inherit;&quot;&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kwd&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(16, 16, 148);&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(43, 145, 175);&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; j &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;lit&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(125, 39, 39);&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;com&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(133, 140, 147);&quot;&gt;// constant object&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;kwd&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(16, 16, 148);&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(43, 145, 175);&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;p &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;com&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(133, 140, 147);&quot;&gt;// `p` is a const access path to `j`&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;

  &lt;/span&gt;&lt;span class=&quot;typ&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(43, 145, 175);&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;q &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(16, 16, 148);&quot;&gt;const_cast&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;typ&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(43, 145, 175);&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;*&amp;gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;com&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(133, 140, 147);&quot;&gt;// `q` is a non-const access path to `j`&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;q &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;lit&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(125, 39, 39);&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;com&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(133, 140, 147);&quot;&gt;// UNDEFINED BEHAVIOR !!!&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그럼 mutable은 뭘까? [1]&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;- mutable로 지정된 멤버는 외부에 노출된 클래스의 상태(the externally visible state of the class)에 영향을 받지 않는다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;- const 클래스의 mutable 멤버는 수정 가능하다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;- c++은 mutable을 storage-class-specifier로 취급한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;mutable이 단순히 상수성을 제거한다는 생각을 했는데, 중요한 포인트중 하나는 class가 const여도 된다는 것이다.&lt;/p&gt;&lt;p&gt;즉,&lt;/p&gt;&lt;p&gt;* const_cast는 애초에 다루는 객체가 const이면 안된다.&lt;/p&gt;&lt;p&gt;* mutable은 다루는 객체가 const여도 modifable하다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위에 적당히 만들어본 Tile &amp;amp; TileStore를 아래처럼 고쳐보았다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;lang-cpp prettyprint prettyprinted&quot; style=&quot;margin-top: 0px; margin-bottom: 1em; padding: 5px; border: 0px; width: auto; max-height: 600px; overflow: auto; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; color: rgb(57, 51, 24); word-wrap: normal; background-color: rgb(239, 240, 241);&quot;&gt;&lt;span style=&quot; color:#000080;&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#008000;&quot;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;
&lt;span style=&quot; color:#000080;&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#008000;&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;br /&gt;
&lt;span style=&quot; color:#808000;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#800080;&quot;&gt;Tile&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;{&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;:&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;   &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#800000;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot; color:#000000;&quot;&gt;};&lt;/span&gt;
&lt;br /&gt;
&lt;span style=&quot; color:#808000;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#800080;&quot;&gt;TileStore&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;{&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;:&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot; color:#800080;&quot;&gt;Tile&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;getTile&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;{&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot; color:#800000;&quot;&gt;empty_tiles_&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;empty&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;())&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;{&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;const_cast&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot; color:#800080;&quot;&gt;TileStore&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;*&amp;gt;(&lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;)-&amp;gt;&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;ReserveMoreTiles&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;();&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;}&lt;/span&gt;
&lt;br /&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#800000;&quot;&gt;empty_tiles_&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot; color:#000080;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;];&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;void&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;ReserveMoreTiles&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;{&lt;/span&gt;
&lt;br /&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot; color:#800080;&quot;&gt;Tile&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;tile&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#800080;&quot;&gt;Tile&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;();&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;tile&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; color:#800000;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000080;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot; color:#800000;&quot;&gt;empty_tiles_&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;push_back&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;tile&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;private&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;:&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot; color:#800080;&quot;&gt;std&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot; color:#800080;&quot;&gt;vector&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot; color:#800080;&quot;&gt;Tile&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;*&amp;gt;&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#800000;&quot;&gt;empty_tiles_&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot; color:#000000;&quot;&gt;};&lt;/span&gt;
&lt;br /&gt;
&lt;span style=&quot; color:#808000;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;main&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;{&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#800080;&quot;&gt;TileStore&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot; color:#800080;&quot;&gt;Tile&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;t&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;getTile&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;();&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;printf&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot; color:#008000;&quot;&gt;&quot;%d\n&quot;&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;t&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; color:#800000;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot; color:#c0c0c0;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot; color:#808000;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot; color:#c0c0c0;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; color:#000080;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot; color:#000000;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot; color:#000000;&quot;&gt;}&lt;/span&gt;
&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;이 동작은 undefined behavior이다. const 객체의 constness를 제거하는 로직이니까.&lt;/p&gt;&lt;p&gt;mutable로 empty_tiles_를 선언해야 맞는 것 같다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;결론적으로 const_cast는 위험하다!&lt;/span&gt; (const 객체 안쓴다고 확신할 수 있는가?)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;PS. 하지만, QT 5.6으로 컴파일뿐 아니라 실행은 잘 된다. (undefined.... != crash)&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;3으로 다시 돌아가서....&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;C++98 single threaded code는 문제 없다. ( 왜 c++98 single threaded code라고 부르는지 모르겠다. )&lt;/p&gt;&lt;p&gt;C++98에서 우리는 const는 논리적인 const(logically const)이며, 물리적인/비트레벨의 const(phisically/bitwise)는 아니다라고 가르쳐왔다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제 C++11에서는 const란 read-only 또는 동시성을 고려해서 안전하게 읽을수 있음(safe to read concurrently)을 보장한다.(해야 한다.)&lt;/p&gt;&lt;p&gt;다시 말해 물리적인/비트레벨의 const이거나 내부적으로 동기화되어 어떠한 쓰기 동작도 concurrent한 read access들로부터 동기화되어야 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;요약해서,&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;const correctness 코드를 짜라.&lt;/p&gt;&lt;p&gt;const를 올바르게 사용하는 것은 올바르게 동기화된 코드를 위해 필요하다. 또 const는 그 자체로 &quot;값을 수정하지 않겠다는&quot; 훌륭한 문서이고 컴파일러가 더 나은 코드를 만드는 것을 도와준다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;cosnt 객체나 동작(메소드)에서 멤버를 수정해야 한다면 mutable을 mutex 또는 atomic과 함께 써라.&lt;/p&gt;&lt;p&gt;모든 상용 라이브러리들이 const correct하진 않다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[ ] &lt;a href=&quot;https://herbsutter.com/2013/05/24/gotw-6b-const-correctness-part-2/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://herbsutter.com/2013/05/28/gotw-6b-solution-const-correctness-part-2/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://herbsutter.com/2013/05/24/gotw-6b-const-correctness-part-2/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;1. 함수를 선언할때 레퍼런스가 아닌 파라미터의 const는 의미 없다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;lang-cpp prettyprint prettyprinted&quot; style=&quot;margin-top: 0px; margin-bottom: 1em; padding: 5px; border: 0px; width: auto; max-height: 600px; overflow: auto; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; color: rgb(57, 51, 24); word-wrap: normal; background-color: rgb(239, 240, 241);&quot;&gt;&lt;code style=&quot;margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; white-space: inherit;&quot;&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;void a(const int);&lt;br /&gt;void a(int); // same&lt;br /&gt;&lt;br /&gt;void b(const int&amp;amp;);&lt;br /&gt;void b(int&amp;amp;); // different&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;그러나 inline 함수는 선언과 정의가 같이 있으니까 적는게 의미가 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;2. 이항 연산자의 overload시 rhs는 const, lhs는 const가 아닌것이 좋다.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// 잘못된 예제 코드&lt;br /&gt;polygon operator+( polygon&amp;amp; lhs, polygon&amp;amp; rhs ) {&lt;br /&gt;    auto ret = lhs;&lt;br /&gt;    auto last = rhs.get_num_points();&lt;br /&gt;    for( auto i = 0; i &amp;lt; last; ++i ) // concatenate&lt;br /&gt;        ret.add_point( rhs.get_point(i) );&lt;br /&gt;    return ret;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;lhs를 ret에 복사하고 있다.&lt;/p&gt;&lt;p&gt;결국 내부에서 한번의 객체 복사가 이뤄져야 하는데, 이 객체가 앞서 호출된 임시객체인 것이 유리할 수 있다.&lt;/p&gt;&lt;p&gt;예를 들어 x = a + b + c;&lt;/p&gt;&lt;p&gt;a + b를 수행하면서 생긴 ret객체를 다시 lhs로 받아서 c와 더하게 된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;즉, 아래와 같이 하는 것이 비용이 적을 가능성이 있다.&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;lang-cpp prettyprint prettyprinted&quot; style=&quot;margin-top: 0px; margin-bottom: 1em; padding: 5px; border: 0px; width: auto; max-height: 600px; overflow: auto; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; color: rgb(57, 51, 24); word-wrap: normal; background-color: rgb(239, 240, 241);&quot;&gt;&lt;code style=&quot;margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; white-space: inherit;&quot;&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;polygon operator+(polygon lhs, const polygon&amp;amp; rhs) {&lt;br /&gt;    // ...&lt;br /&gt;    return lhs;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참조&lt;/p&gt;&lt;p&gt;[1] http://en.cppreference.com/w/cpp/language/cv&lt;br /&gt;&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <category>C++</category>
      <category>const</category>
      <category>const_cast</category>
      <category>herbsutter</category>
      <category>mutable</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/451</guid>
      <comments>https://bunhere.tistory.com/451#entry451comment</comments>
      <pubDate>Tue, 18 Oct 2016 10:13:24 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] std::function의 성능</title>
      <link>https://bunhere.tistory.com/437</link>
      <description>&lt;p&gt;std::function의 성능이 생각보다 많이 느리다는 것을 알게 되었다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block;   height: auto; max-width: 100%;&quot;&gt;&lt;a href=&quot;https://t1.daumcdn.net/cfile/tistory/25324E435567B4DA3A&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://i1.daumcdn.net/cfs.tistory/v/0/blog/image/extension/unknown.gif&quot; style=&quot;vertical-align: middle;&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;test.cpp&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;ryuan@webkit:~$ g++ ./test.cpp --std=c++11 -O3 -DINTERFACE_VERSION&lt;br /&gt;ryuan@webkit:~$ ./a.out&lt;br /&gt;main:96] 8 elapsed&lt;br /&gt;ryuan@webkit:~$ g++ ./test.cpp --std=c++11 -O3 -DINTERFACE_VERSION_NO&lt;br /&gt;ryuan@webkit./a.out&lt;br /&gt;main:96] 437 elapsed&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;못쓰겠네 -_-;&lt;/p&gt;&lt;p&gt;http://probablydance.com/2013/01/13/a-faster-implementation-of-stdfunction/&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[Update]&lt;/p&gt;&lt;p&gt;Modern Effective C++ Item 5 에 따르면&lt;/p&gt;&lt;p&gt;std::function은 단순히 closure와 유사한 것이 아니라 모든 callable object를 담는 것으로...&lt;/p&gt;&lt;p&gt;추가적인 heap 메모리를 사용하는 것 같다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위 예제를 auto로 바꿔서 테스트해봐야겠다.&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/437</guid>
      <comments>https://bunhere.tistory.com/437#entry437comment</comments>
      <pubDate>Fri, 29 May 2015 09:38:42 +0900</pubDate>
    </item>
    <item>
      <title>[EFL] EWebKit Extension</title>
      <link>https://bunhere.tistory.com/428</link>
      <description>&lt;p&gt;ewebkit (WebKit/Efl)은 최근 WebKit1 포트를 제거했습니다. 옛날 코드를 사용하지 않는다면, WebKit2만 사용이 가능한 셈입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 둘의 가장 큰 차이는 이전에 적었던 글에서도 이야기한 것처럼 단일 프로세스를 통해 실행되느냐, 멀티 프로세스 환경에서 실행되는가입니다.&lt;/p&gt;&lt;p&gt;따라서 사용자의 요청(예를 들어 url을 로드해라, resize해라)등은 프로세스간 통신(IPC)을 거쳐 웹 컨텐츠를 담당하는 WebProcess에게 전달됩니다.&lt;/p&gt;&lt;p&gt;그러나 이러한 IPC 메커니즘을 통해 처리하기 어려운 것들이 있습니다. 대표적인 것이 JavaScript binding입니다. JavaScript binding은 native 코드를 javascript interface로 컨텐츠에 추가하여 web page에서 해당 interface를 통해 native code를 수행할 수 있게 하는 방법입니다.&lt;/p&gt;&lt;p&gt;WebKit2에서 이러한 것들을 수행하기 위해서는 WebProcess에서 사용자의 코드들을 수행할 수 있어야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이를 위해 Injected Bundle이라는 것을 WebKit2에서는 제공하고 있습니다.&lt;/p&gt;&lt;p&gt;그러나 Injected Bundle은 WebKit2의 인터페이스를 사용하고 있기 때문에, ewebkit은 이를 한단계 감싼 ewk_extension 을 제공합니다.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/273D9B3456E65D3F03&quot; alt=&quot;&quot; height=&quot;281&quot; width=&quot;648&quot;&gt;&lt;/p&gt;&lt;p&gt;그림으로 보면 위와 같습니다.&lt;/p&gt;&lt;p&gt;EWebKit2_Extension을 쓰려고 하는 사용자는 EWebKit2_Extension을 이용하여 extension을 만들어야 합니다.&lt;/p&gt;&lt;p&gt;이 때, 반드시 &quot;void ewk_extension_init(Ewk_Extension *extension)&quot; 을 구현하여야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또, user application 에서는 ewk_context_new_with_&lt;ins&gt;ex&lt;/ins&gt;&lt;ins&gt;te&lt;/ins&gt;&lt;ins&gt;nsions&lt;/ins&gt;_path()를 사용하여 자신이 작성한 extension 라이브러리의 path를 건네주어야 합니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ewebkit은 WebProcess를 실행(fork)할 때, WebProcess가 호출할 injected bundle, 즉 ewebkit_extension_manager의 위치와 사용자 extension의 위치를 같이 넘겨줍니다.&lt;/p&gt;&lt;p&gt;WebProcess는 실행 직후 ewebkit_extension_manager를 로드(dlopen)하고 extension_manager가 extension을 로드하면 extension을 쓸 준비는 끝나게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;extension은 이후 WebProcess에 자신이 원하는 타이밍에 WebProcess로부터 콜백들을 받고 적절한 일(javascript binding같은)을 수행할 것이며, message를 이용하여 user application과 서로 통신하게 될 것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;간단한 extension의 예제는 아래에 있습니다.&lt;/p&gt;&lt;p&gt;https://github.com/ewebkit/samples/tree/master/devs/ryuan/extensions&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>개발</category>
      <category>EFL</category>
      <category>ewebkit</category>
      <category>ewebkit2</category>
      <category>injected bundle</category>
      <category>WebKit2/Efl</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/428</guid>
      <comments>https://bunhere.tistory.com/428#entry428comment</comments>
      <pubDate>Tue, 23 Sep 2014 09:07:43 +0900</pubDate>
    </item>
    <item>
      <title>transparent ewebkit</title>
      <link>https://bunhere.tistory.com/424</link>
      <description>&lt;p&gt;기존 글:&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/417&quot;&gt;Hello, ewebkit&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이번에는 ewk_view에 투명한 배경을 주는 예제를 소개할까 합니다.&lt;/p&gt;&lt;p&gt;기존의 예제(simple.c)를 약간 수정하는 정도의 예제입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;먼저 투명한 배경에 대한 설명을 하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;일반적으로 웹 페이지는 웹뷰(ewk_view)의 전체 영역에 컨텐츠를 그리게 됩니다.&lt;/p&gt;&lt;p&gt;웹페이지는 body 태그의 배경을 이용하여 컨텐츠의 배경색을 갖게 되는데, 보통 다음과 같이 사용합니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### html&lt;/p&gt;&lt;p&gt;&amp;lt;!doctype html&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;lt;!- no background --&amp;gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;body&amp;gt;HELLO&amp;lt;/body&amp;gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### html&lt;/p&gt;&lt;p&gt;&amp;lt;!doctype html&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;lt;body bgcolor=&quot;red&quot;&amp;gt;Hello, I am red background&amp;lt;/body&amp;gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### html&lt;/p&gt;&lt;p&gt;&amp;lt;!doctype html&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;lt;head&amp;gt;&amp;lt;style&amp;gt;body { background-color: green; } &amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;body&amp;gt;Hello, I am green background&amp;lt;/body&amp;gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;두번째와 세번째는 배경을 갖는 예제인 반면, 첫번째는 배경을 갖지 않는 예제입니다. 그러나 만약 첫번째 예제를 브라우저에서 실행한다면 흰 배경 위에 HELLO라는 글자가 적혀 있는 것을 보게 될 것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;일반적으로 거의 대부분의 브라우저들은 기본 배경을 흰색으로 제공하고 있습니다.&lt;/p&gt;&lt;p&gt;그래서 웹 컨텐츠를 제작하는 대부분의 분들이 배경을 지정하지 않고 있습니다.&lt;/p&gt;&lt;p&gt;(&lt;/p&gt;&lt;p&gt;하지만 만약 흰 배경을 사용하지 않는 브라우저가 나타나면 어쩌실건가요? ㅡ.ㅡ&lt;/p&gt;&lt;p&gt;그리고, 특정 모바일 디스플레이들은 흰색일 때 배터리 소모가 극심합니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;webkit도 기본 배경을 흰색으로 정하고 있지만, 다른 색을 쓰거나, 투명하게 그릴 수 있는 방법을 제공하고 있습니다.&lt;/p&gt;&lt;p&gt;ewebkit에서 관련 API는 ewk_view_bg_color_set 이라는 API가 존재합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;/**&lt;br /&gt;&amp;nbsp;* Sets the background color and transparency of the view.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;*&lt;br /&gt;&amp;nbsp;* @param o view object to change the background color&lt;br /&gt;&amp;nbsp;* @param r red color component&lt;br /&gt;&amp;nbsp;* @param g green color component&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;* @param b blue color component&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;* @param a transparency&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;*/&lt;br /&gt;EAPI void ewk_view_bg_color_set(Evas_Object *o, int r, int g, int b, int a);&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;각각의 color component들은 0 부터 255 사이의 숫자여야 합니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;일반적으로 EFL에서는 evas_object_color_set이라는 API를 이용하여 evas object의 색을 지정했지만,&lt;/p&gt;&lt;p&gt;ewebkit에서는 alpha를 제외하곤 evas_object_color_set의 다른 인자들을 사실상 무시합니다.&lt;/p&gt;&lt;p&gt;이유는, evas_object_color_set의 alpha가 전체 컨텐츠의 opacity를 다루는 반면, ewebkit은 배경만의 opacity를 다루어야 하는 요구사항이 있기 때문입니다.&lt;/p&gt;&lt;p&gt;즉, evas_object_color_set은 evas_object 전체의 색을 조절하는 API로 ewebkit에서는 contents의 색은 contents가 지정해야 하기 때문에 RGB값은 무시됩니다. (현재)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ewk_view_bg_color_set 을 사용하는 예제는 아래와 같습니다.&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;https://github.com/ewebkit/samples/blob/master/devs/ryuan/transparent.c&quot;&gt;https://github.com/ewebkit/samples/blob/master/devs/ryuan/transparent.c&lt;/a&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++ &lt;br /&gt;&lt;/p&gt;&lt;p&gt;// gcc transparent.cpp `pkg-config --cflags --libs elementary ewebkit2&lt;br /&gt;#include &amp;lt;Elementary.h&amp;gt;&lt;br /&gt;#include &amp;lt;EWebKit2.h&amp;gt;&lt;br /&gt;&lt;br /&gt;void on_done(void *userData, Evas_Object *webView, void *eventInfo)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_exit();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;EAPI_MAIN int&lt;br /&gt;elm_main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; ewk_init();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; Evas_Object* win;&lt;br /&gt;&amp;nbsp;&amp;nbsp; win = elm_win_add(NULL, &quot;sample&quot;, ELM_WIN_BASIC);&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_win_title_set(win, &quot;sample&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_smart_callback_add(win, &quot;delete,request&quot;, on_done, NULL);&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_win_autodel_set(win, EINA_TRUE);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; Evas_Object* bg = elm_bg_add(win);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_bg_color_set(bg, 0, 0, 255);&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_win_resize_object_add(win, bg);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_show(bg);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; Evas_Object* ewk = ewk_view_add(evas_object_evas_get(win));&lt;br /&gt;&amp;nbsp;&amp;nbsp; ewk_view_html_string_load(ewk, &quot;&amp;lt;!doctype html&amp;gt;&amp;lt;body&amp;gt;HELLO&amp;lt;/body&amp;gt;&quot;, NULL, NULL);&lt;br /&gt;&amp;nbsp;&amp;nbsp; ewk_view_bg_color_set(ewk, 0, 0, 0, 0);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_resize(ewk, 400, 400);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_move(ewk, 0, 0);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_show(ewk);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_resize(win, 400, 400);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_show(win);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_run();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; ewk_shutdown();&lt;br /&gt;}&lt;br /&gt;ELM_MAIN()&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;배경 속성이 없는 web contents를 위해 url 대신 ewk_view_html_string_load를 이용했습니다.&lt;/p&gt;&lt;p&gt;그리고 ewk_view_bg_color_set 을 통해 ewk_view의 배경을 투명하게 만든 예제입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위에서 elm_bg의 색을 blue로 했기 때문에 파란색 배경 위에 HELLO라는 글자가 적혀있어야 합니다.&lt;/p&gt;&lt;p&gt;만약 검은색으로 나온다면, ewebkit을 최신으로 빌드해보시기 바랍니다.&lt;/p&gt;&lt;p&gt;(최근 수정 :&lt;a href=&quot;https://bugs.webkit.org/show_bug.cgi?id=135333&quot; target=&quot;_blank&quot;&gt;https://bugs.webkit.org/show_&lt;wbr&gt;bug.cgi?id=135333&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;추신. 현재 ewk_view_bg_color_set과 EFL 관련 버그가 하나 더 있는 것 같습니다.&lt;/p&gt;&lt;p&gt;만약 ewk_view_bg_color_set의 RGB요소에 값을 주고 alpha를 준 경우, elm_bg의 색과 blend되고 있습니다.&lt;/p&gt;&lt;p&gt;만약 투명한 웹뷰가 필요한 경우라면 RGB요소를 모두 0으로 주시기 바랍니다.&lt;/p&gt;</description>
      <category>개발</category>
      <category>EFL</category>
      <category>ewebkit</category>
      <category>Webkit</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/424</guid>
      <comments>https://bunhere.tistory.com/424#entry424comment</comments>
      <pubDate>Wed, 30 Jul 2014 05:43:54 +0900</pubDate>
    </item>
    <item>
      <title>CSS pixel 이란 무엇인가?</title>
      <link>https://bunhere.tistory.com/422</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 픽셀(pixel)은 아래처럼 설명할 수 있습니다.[1][2]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;In &lt;a title=&quot;Digital imaging&quot; href=&quot;http://en.wikipedia.org/wiki/Digital_imaging&quot;&gt;digital imaging&lt;/a&gt;, a &lt;b&gt;pixel&lt;/b&gt;, &lt;b&gt;pel&lt;/b&gt;,&lt;sup id=&quot;cite_ref-1&quot; class=&quot;reference&quot;&gt;&lt;/sup&gt;or &lt;b&gt;picture element&lt;/b&gt;&lt;sup id=&quot;cite_ref-2&quot; class=&quot;reference&quot;&gt;&lt;/sup&gt; is a physical point in a &lt;a title=&quot;Raster graphics&quot; href=&quot;http://en.wikipedia.org/wiki/Raster_graphics&quot;&gt;raster image&lt;/a&gt;, or the smallest addressable element in an &lt;a title=&quot;All points addressable&quot; href=&quot;http://en.wikipedia.org/wiki/All_points_addressable&quot;&gt;all points addressable&lt;/a&gt; &lt;a title=&quot;Display device&quot; href=&quot;http://en.wikipedia.org/wiki/Display_device&quot;&gt;display device&lt;/a&gt;; so it is the smallest controllable element of a picture represented on the screen.&quot; (출처 : wikipedia)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흔히 TV/모니터는 얼마나 많은 픽셀을 표현하는지를 (display) resolution이라고 부르며 (물리적인) 픽셀로 처리합니다.[3]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;( &lt;a class=&quot;tx-link&quot; href=&quot;http://bunhere.tistory.com/211&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해상도&lt;/a&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://bunhere.tistory.com/211&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; 관련 글&lt;/a&gt; )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 그동안 프로그래밍을 하는 과정에서 픽셀이라는 개념은 물리적인 스크린의 한 점과 같다고 생각해 왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 모바일 (그리고 모바일 웹)에서 이러한 픽셀의 개념에 큰 혼란이 생겨 개인적으로 조사한 내용을 적으려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;아이폰의 등장&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2007년 초 아이폰과 이후 안드로이드의 등장으로 모바일 디바이스는 스마트폰(그전에도 존재했지만)의 세상이 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이들 스마트폰이 등장하면서 모바일 브라우저는 기존 웹 페이지를 '거의' 문제 없이 모바일에서 렌더링할 수 있게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;레티나 디스플레이의 등장&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2010년 애플은 아이폰4에 레티나 디스플레이라는 화면 구성을 가져옵니다. 이는 기존의 아이폰 3에 비해 사실상 두배의 해상도를 갖는 디스플레이(640 x 960)입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(사실 레티나 디스플레이에서 중요한 것은 DPI 로 특정 시야거리에서 기존의 160 ppi 의 두배인 326 ppi 를 만족한다는 의미로 레티나라고 불렀던 것으로 압니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에서 한가지 문제점은 기존의 앱/웹페이지들이 320 x 480에 최적화 되어 있다는 것이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해 애플은 웹의 경우 device pixel ratio 라는 요소를 가져왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, device의 width는 320으로 놓고 대신 pixel ratio의 값을 2로 설정하도록 한 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 새로운 픽셀의 정의가 생겨나고 말았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹페이지는 contents가 320픽셀이라고 생각하지만, 실제 물리적인 픽셀은 640픽셀인 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 말해 우리가 width=100 px 의 DIV태그를 만들면 화면상에는 200px의 박스가 그려지게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;안드로이드의 따라하기.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후발주자인 안드로이드는 어쩔수 없이 애플이 만들어놓은 컨텐츠를 잘 그리기 위해서 아이폰의 많은 부분을 그대로 차용하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 레티나급 디바이스에 대해 유사하게 2.0의 device pixel ratio를 사용하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 안드로이드는 정말 많은 디바이스가 존재하고 각 디바이스들이 전부 ppi가 달랐습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;target-density라는 개념을 통해 device 별로 테이블을 만들고 했지만, 문제는 간단하지 않았던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;device pixel ratio는 아이폰의 의미와 약간 다르게 device의 ppi를 고려하여 1.5 2.0 3.0등 다양한 값을 갖게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서, 이 값이 실제 1.0 일 때의 ppi에 정확히 비례하지 않을 뿐 아니라, 실제 단말의 픽셀과도 정확히 일치하지 않게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 1.5 의 단말의 픽셀이 320 x 1.5 = 480 px 이 아닌 단말들도 많아지게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2013년 target-density는 deprecated되었습니다.(&lt;a href=&quot;https://petelepage.com/blog/2013/02/viewport-target-densitydpi-support-is-being-deprecated/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://petelepage.com/blog/2013/02/viewport-target-densitydpi-support-is-being-deprecated/&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;사실 w3c에서는...&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 웹 표준인 w3c에서는픽셀에 대한 정의를 &quot;Reference pixel&quot;이라고 정의하고 있었습니다. [4]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://t1.daumcdn.net/cfile/tistory/262D994E53D6542414?original&quot; data-phocus=&quot;https://t1.daumcdn.net/cfile/tistory/262D994E53D6542414?original&quot; data-alt=&quot;Showing that pixels must become larger if the viewing distance increases&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/262D994E53D6542414&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F262D994E53D6542414&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;360&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Showing that pixels must become larger if the viewing distance increases&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The &lt;b&gt;&lt;dfn id=&quot;reference-pixel&quot; data-dfn-type=&quot;dfn&quot; data-export=&quot;&quot;&gt;reference pixel&lt;/dfn&gt;&lt;/b&gt; is the visual angle of one pixel on a device with a pixel density of 96dpi and a distance from the reader of an arm&amp;rsquo;s length. For a nominal arm&amp;rsquo;s length of 28 inches, the visual angle is therefore about 0.0213 degrees. For reading at arm&amp;rsquo;s length, 1px thus corresponds to about 0.26&amp;nbsp;mm (1/96&amp;nbsp;inch).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애초에 물리 픽셀 과 논리 픽셀을 구분해둔 셈입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 모니터는 팔길이 정도의 시야거리(viewing distance)를 갖고 있고 96 dpi 였습니다. 웹 표준을 만들 때 이미 시야거리의 변화와 dpi의 변화를 고려하여 가상의 픽셀인 reference pixel을 정의하고 있었고 웹은 이 값에 기반하여 cm, inch등으로 픽셀값을 변환할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 모바일 벤더들은 96dpi를 바꾸지 않았습니다.(여러가지 문제가 있었을 거라고 생각됩니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 160dpi나 326dpi인 아이폰에서도 1 픽셀을 인치로 변환하면 1/96이 나오게 된 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아이폰과 같은 모바일의 시야거리는 대략 10 inch (25cm) 라고 생각할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대충 계산하면 동일한 시야각을 얻으려면 픽셀은 0.1 mm 여야 할듯 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0.26 : 71 = x : 25&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 말해 모니터와 같은 reference pixel(같은 시야각을 같는 픽셀)을 얻으려면 대략 243 dpi가 나와야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 현재 모바일은 160 dpi를 de-factor처럼 사용하고 있는 셈입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;심지어, 그 값도 단말에 따라 약간씩 다릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;결론적으로&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 웹에서 현재 있는 cm , inch 등은 printer를 media type을 위해서 사용해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; px과 cm간의 변환은 사실상 의미를 잃어버렸습니다. (계산은 되지만, 실제 물리적인 길이를 의미하지 않습니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. px 정보(screen.width window.clientWidth) 를 이용하여 디바이스의 크기를 알아내는 것은 사실상 불가능해졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 현재의 웹은 디바이스의 크기를 알 방법을 제공하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 당연히 디바이스의 크기를 구분할 수 있는 올바른 방법은 존재하지 않고 미디어쿼리나 user agent를 통해 이미 알고 있는 디바이스만을 고려할 수 있게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 :&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://ko.wikipedia.org/wiki/%ED%99%94%EC%86%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[1] &lt;/a&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://ko.wikipedia.org/wiki/%ED%99%94%EC%86%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;(한글) http://ko.wikipedia.org/wiki/%ED%99%94%EC%86%8C&lt;/a&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://en.wikipedia.org/wiki/Pixel&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[2] &lt;/a&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://ko.wikipedia.org/wiki/%ED%99%94%EC%86%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;(영문) &lt;/a&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://en.wikipedia.org/wiki/Pixel&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://en.wikipedia.org/wiki/Display_resolution&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[3] http://en.wikipedia.org/wiki/Display_resolution&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://dev.w3.org/csswg/css-values/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[4] http://dev.w3.org/csswg/css-values/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://ko.wikipedia.org/wiki/%EB%A0%88%ED%8B%B0%EB%82%98_%EB%94%94%EC%8A%A4%ED%94%8C%EB%A0%88%EC%9D%B4&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://alistapart.com/article/a-pixel-identity-crisis/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://alistapart.com/article/a-pixel-identity-crisis/&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/422</guid>
      <comments>https://bunhere.tistory.com/422#entry422comment</comments>
      <pubDate>Fri, 25 Jul 2014 09:37:31 +0900</pubDate>
    </item>
    <item>
      <title>Tizen Wearable SDK 예제 사진</title>
      <link>https://bunhere.tistory.com/418</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Tizen Wearable SDK beta 1.0 이 릴리즈 되었습니다.&lt;/p&gt;&lt;p&gt;( &lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://developer.samsung.com/samsung-mobile-sdk/&quot;&gt; http://developer.samsung.com/samsung-mobile-sdk/&lt;/a&gt; )&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래는 기본으로 설치되어 있는 예제들 사진입니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 650px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/21637C4E53277ED60B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F21637C4E53277ED60B&quot; width=&quot;650&quot; height=&quot;366&quot; filename=&quot;sc.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;에뮬레이터와 Analog watch 화면&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 650px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/256A5E475327802118&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F256A5E475327802118&quot; width=&quot;650&quot; height=&quot;366&quot; filename=&quot;Screenshot from 2014-03-18 08:05:52.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;카메라 앱과 에뮬레이터 콘트롤 패널&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 384px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2415EE49532782C523&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2415EE49532782C523&quot; width=&quot;384&quot; height=&quot;440&quot; filename=&quot;Screenshot from 2014-03-18 08:16:24.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 384px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/255CB049532782C514&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F255CB049532782C514&quot; width=&quot;384&quot; height=&quot;440&quot; filename=&quot;Screenshot from 2014-03-18 08:17:03.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Open Source</category>
      <category>Tizen</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/418</guid>
      <comments>https://bunhere.tistory.com/418#entry418comment</comments>
      <pubDate>Tue, 18 Mar 2014 08:18:38 +0900</pubDate>
    </item>
    <item>
      <title>Hello ewebkit?</title>
      <link>https://bunhere.tistory.com/417</link>
      <description>&lt;p&gt;ewebkit은 WebKit 엔진 기반에 EFL 라이브러리를 사용하여 UI를 표현하는 라이브러리입니다.&lt;/p&gt;&lt;p&gt;(WebKit/EFL 이라고도 부르는데,&amp;nbsp; 저는 so 파일 이름에 따라 ewebkit이라고 부르고 있습니다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;물론,&amp;nbsp; Elementary의 elm_web이 ewebkit 에서 사용하는 ewk_view의 간단한 wrapper 클래스이지만 아직 문제가 많은 상태이기 때문에(1.9) ewebkit을 직접 쓰는 방법을 권장하고 있습니다. (또 타이젠(~2.2) 에서는 elm_web을 사용하실 수 없습니다.)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 글에서는 elm_web이 아닌 ewk_view를 사용해서 간단한 페이지를 만드는 법을 공유하려고 합니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ewebkit 라이브러리는 현재 두 종류가 있습니다.&lt;/p&gt;&lt;p&gt;ewebkit : WebKit1/EFL 포트에 기반하는 라이브러리&lt;/p&gt;&lt;p&gt;ewebkit2 : WebKit2/EFL 포트에 기반하는 라이브러리&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;둘의 가장 큰 차이는 간단히 설명드리면 웹페이지를 렌더링하는 코어영역을 같은 프로세스에서 처리하느냐(ewebkit), 다른 프로세스에서 처리하느냐(ewebkit2) 입니다.&lt;/p&gt;&lt;p&gt;대부분의 인터페이스는 유사하지만, 이런 프로세스 모델의 차이에서 몇몇 인터페이스에는 차이가 있습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참고로 타이젠과 같은 경우 1.0에서는 ewebkit을 사용하였고, 2.0부터는 ewebkit2를 사용하고 있습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;(현재 ewebkit은 webkit.org에서 제거되어 ewebkit2만 남았습니다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(93, 93, 93);&quot;&gt;ewebkit을 사용한 코드들은 elm_web (http://git.enlightenment.org/core/elementary.git/tree/src/lib/elm_web.c) 이나 WebKit 프로젝트 내의 http://trac.webkit.org/browser/trunk/Tools/EWebLauncher/main.c 가있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;ewebkit2를 사용한 코드들은 elm_web2(http://git.enlightenment.org/core/elementary.git/tree/src/lib/elm_web2.c),&amp;nbsp; 또는 WebKit 프로젝트 내의 http://trac.webkit.org/browser/trunk/Tools/MiniBrowser/efl/main.c 가 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참고삼아 보시면 될 듯 하고, 이 글에서는 ewebkit2 의 코드를 MiniBrowser 기반으로 설명을 드리려고 합니다.&lt;/p&gt;&lt;p&gt;(http://trac.webkit.org/browser/trunk/Tools/MiniBrowser/efl/main.c 정도의 설명입니다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;혹시 EFL 에 대해서 잘 모르신다면, 이 글을 읽기에 부담스러우실 수 있습니다.&lt;/p&gt;&lt;p&gt;(과감히 뒤로가기를 누르셔도 됩니다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;(&lt;/p&gt;&lt;p&gt;혹, EFL에 관심이 있으시면 먼저 아래 글을 보시는 것을 추천드립니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;https://events.linuxfoundation.org/images/stories/pdf/lfcs2012_raster.pdf&quot;&gt;https://events.linuxfoundation.org/images/stories/pdf/lfcs2012_raster.pdf&lt;/a&gt;&lt;/p&gt;&lt;p&gt;)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;1. 생성 / 소멸&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;다른 EFL 라이브러리들처럼 ewebkit/ewebkit2도 전역의&amp;nbsp; _init 과&amp;nbsp; _shutdown 을 가지고 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;int main ()&lt;/p&gt;&lt;p&gt;{&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewk_init();&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewk_shutdown();&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;/p&gt;&lt;p&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;반드시 사용하기 전에 호출해주셔야 합니다.&lt;/p&gt;&lt;p&gt;가능하면 main 시작하자마자 ewk_init을 호출하고, loop가 끝난 후 ewk_shutdown을 호출해주시는 것이 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;다음으로,ewk_view 객체를 만들어야 합니다.&lt;/p&gt;&lt;p&gt;ewk_view를 만드는 방법은 여러가지가 있습니다. 하나씩 살펴보도록 하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1) ewk_view_add(Evas *e)&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ewk_view_add 는 ewk_view를 만드는 가장 쉬운 방법입니다.&lt;/p&gt;&lt;p&gt;간단한 페이지를 로드하는 데는 적합하지만, alert/prompt/confirm이라던가 새창을 열거나 그 밖에 UI의 도움을 받아야 하는 많은 것들을 할 수 없습니다.&lt;/p&gt;&lt;p&gt;또, ewebkit에서는 관계없으나 ewebkit2에서는 매 evas object가 별도의 WebProcess를 생성하여 동작하게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;Evas_Object *o = ewk_view_add(e);&lt;/p&gt;&lt;p&gt;ewk_view_url_set(o, &quot;http://bunhere.tistory.com&quot;);&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2) ewk_view_add_with_context(Evas *e, Ewk_Context *context)&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ewebkit에서는 없는 함수입니다.&lt;/p&gt;&lt;p&gt;ewebkit2에서는 web context 라는 것이 있어서 하나의 web context는 하나의 WebProcess를 생성하게 합니다. 만약 이미 생성한 web context 안에 웹뷰를 만들려고 하면 이 함수를 사용해서 생성하면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;// o 와 같은 context(web process)에서 동작하는 ewk_view를 생성&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Evas_Object *o2 = ewk_view_add_with_context(e, ewk_view_context_get(o));&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;3) ewk_view_smart_add(Evas *e, Evas_Smart *smart, Ewk_Context *context, Ewk_Page_Group *group)&lt;/b&gt;&lt;/p&gt;&lt;p&gt;해당 API는 ewebkit에는 없습니다.(유사한 방법이 있으나 별도의 API 로 존재하지 않습니다.)&lt;/p&gt;&lt;br /&gt;이 API 를 쓰면 ewk_view가 할 수 있는 일을 모두 할 수 있습니다.&lt;p&gt;물론 그만큼 사용하기 어렵다는 문제도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;먼저, 인자들을 하나씩 살펴보도록 하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;Evas *e&lt;/span&gt;&lt;/p&gt;&lt;p&gt;현재 생성하는 ewk_view의 기반이 될 canvas입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;Evas_Smart *smart&lt;/span&gt;&lt;/p&gt;&lt;p&gt;ewk_view는 여러 Evas_Object들 중 smart object로 만들어졌습니다.&lt;/p&gt;&lt;p&gt;Smart Object를 만드는 것에 대한 자세한 내용은 아래 글을 참고하시면 좋을 것 같습니다.&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://docs.enlightenment.org/stable/efl/Example_Evas_Smart_Objects.html&quot;&gt;http://docs.enlightenment.org/stable/efl/Example_Evas_Smart_Objects.html&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;일반적으로 smart object를 만들때는 smart class를 만들어서 evas_object_smart_add를 호출하면 되지만, ewk_view는 추가로 처리해야 하는 인자들이 있어서 ewk_view_smart_add를 대신 사용합니다.&lt;/p&gt;&lt;p&gt;ewk_view_smart_add는 내부적으로 evas_object_smart_add의 일을 수행하게 됩니다.&lt;/p&gt;&lt;p&gt;(ewebkit은 evas_object_smart_add를 사용합니다.)&lt;/p&gt;&lt;p&gt;Evas_Smart를 만드는 법은 복잡하기 때문에 아래에서 다시 설명하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;Ewk_Context *context&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;여러 ewk_view는 하나의 context를 가질 수도 있고, 여러개의 context를 가질 수도 있습니다.&lt;/p&gt;&lt;p&gt;하나의 context에 기반한 ewk_view들은 많은 것을 공유하게 됩니다.&lt;/p&gt;&lt;p&gt;특히 하나의 프로세스에서 수행되게 될 것입니다.&lt;/p&gt;&lt;p&gt;context를 구하려면 기존의 ewk_view 를 이용하여 ewk_view_context_get(o)을 하거나, ewk_context_default_get()을 이용하여 default context를 생성하면 됩니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;Ewk_Page_Group *group&lt;/span&gt;&lt;/p&gt;&lt;p&gt;page
 group을 이해하는 쉬운 예제는 자바스크립트로 실행한 새창입니다. 자바스크립트로 새창을 열면 해당 페이지와 새로 열린 페이지는
 opener / child 관계를 갖게 됩니다. 이 두 페이지는 같은 세팅을 가져야 합니다. 세션도 공유할 것이고요.&lt;/p&gt;&lt;p&gt;이렇게 같은 설정을 가져야 하고 정보들을 공유해야 한다면 같은 page group으로 묶어야 합니다.&lt;/p&gt;&lt;p&gt;page group을 얻는 방법은 기존의 ewk_view를 이용하여 ewk_view_page_group(o)을 호출하거나 ewk_page_group_create(group_name) 을 호출하여 특정 그룹을 생성하면 됩니다. group_name이 null이면 임의의 그룹을 생성하게 됩니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Evas_Smart 만들기&lt;/p&gt;&lt;p&gt;Evas_Smart를 만들려면 smart class를 하나 만들어야 합니다. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;특히 ewk_view를 위한 smart class는 Evas_Smart_Class 를 확장한 Ewk_View_Smart_Class입니다.&lt;/p&gt;&lt;p&gt;사용자는 Ewk_View_Smart_Class를 확장하거나, Ewk_View_Smart_Class를 고쳐서 쓸 수 있습니다.&lt;/p&gt;&lt;p&gt;확장을 해서 쓸 경우, 기본 구현을 오버라이드하여 이용하기 좋다는 장점이 있습니다만, 대부분의 경우에는 기본 구현이 없습니다.(마우스/터치 이벤트 제외)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 글에서는 일단 Ewk_View_Smart_Class를 고쳐서 쓰려고 합니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;###&amp;nbsp; c++&lt;/p&gt;&lt;p&gt;static Ewk_View_Smart_Class *miniBrowserViewSmartClass()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static Ewk_View_Smart_Class ewkViewClass = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION(&quot;MiniBrowser_View&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &amp;amp;ewkViewClass;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;MiniBrowser에서 발췌한 코드로 Ewk_View_Smart_Class 객체를 하나 만들어서 MiniBrowser_View라는 이름으로 초기화했습니다.&lt;/p&gt;&lt;p&gt;이 때, 값들은 모두 NULL로 초기화 될 것입니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ewk_view가 제공하는 메소드들로 재정의하기 위해서 ewk_view_smart_class_set을 호출해 주어야 합니다.&lt;/p&gt;&lt;p&gt;사실 ewk_view는 재정의할 메소드들이 별로 없습니다만 이 함수는 반드시 호출되어야 합니다. 가장 중요한 Evas_Smart_Class의 메소드들이 연결될 것입니다.&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!ewk_init())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return EXIT_FAILURE;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewk_view_smart_class_set(miniBrowserViewSmartClass());&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;이제 어플리케이션에서 필요로 하는 기능들에 대해 추가로 수정을 하시면 됩니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ewk_View_Smart_Class *ewkViewClass = miniBrowserViewSmartClass();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;run_javascript_alert = on_javascript_alert;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;run_javascript_confirm = on_javascript_confirm;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;run_javascript_prompt = on_javascript_prompt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;window_geometry_get = on_window_geometry_get;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;window_geometry_set = on_window_geometry_set;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;fullscreen_enter = on_fullscreen_enter;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;fullscreen_exit = on_fullscreen_exit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;window_create = on_window_create;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;window_close = on_window_close;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;popup_menu_show = on_popup_menu_show;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;popup_menu_hide = on_popup_menu_hide;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;context_menu_show = on_context_menu_show;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;context_menu_hide = on_context_menu_hide;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;input_picker_color_request = on_color_picker_request;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ewkViewClass-&amp;gt;input_picker_color_dismiss = on_color_picker_dismiss;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;앞서 말씀 드린 것과 같이 마우스 이벤트와 같은 몇몇 이벤트를 제외하면 ewkViewClass가 추가한 메소드들은 특수한 구현들을 갖고 있지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;각각의 메소드들이 어떤 인자들과 반환값을 가져야 하는지는 http://trac.webkit.org/browser/trunk/Source/WebKit2/UIProcess/API/efl/ewk_view.h 를 참고하셔야 합니다.&lt;/p&gt;&lt;p&gt;몇몇 메소드들은 아래에서 좀 더 설명하도록 하겠습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이렇게 smart class가 준비되었다면 Evas_Smart를 만들면 됩니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;Evas_Smart *smart = evas_smart_class_new(&amp;amp;ewkViewClass-&amp;gt;sc);&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;sc는 Evas_Smart_Class를 가르키는 주소입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래는 MiniBrowser에서 ewk_view_smart_add를 호출하는 일부 코드입니다..&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Evas *evas = evas_object_evas_get(window-&amp;gt;elm_window);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Evas_Smart *smart = evas_smart_class_new(&amp;amp;ewkViewClass-&amp;gt;sc);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ewk_Context *context = opener ? ewk_view_context_get(opener) : ewk_context_default_get();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ewk_Page_Group *pageGroup = opener ? ewk_view_page_group_get(opener) : ewk_page_group_create(&quot;&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; window-&amp;gt;ewk_view = ewk_view_smart_add(evas, smart, context, pageGroup);&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;생성과 달리 소멸은 간단히 evas_object_del을 호출해주면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;2. Load contents&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;ewebkit에서 contents를 읽는 방법은 두가지가 있습니다.&lt;br /&gt;가장 기본적인 방법인 url을 읽는 방법과, html string을 읽는 방법입니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;url을 읽는 API는 다음과 같습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;ewk_view_url_set(view, &quot;http://bunhere.tistory.com&quot;);&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;그 다음은 알아서 로딩이 된 후, 화면에 그려지게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;html string을 직접 읽는 방법도 크게 어렵지는 않습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;ewk_view_html_string_load(view, &quot;&amp;lt;!doctype html&amp;gt;&amp;lt;body&amp;gt;hello&amp;lt;/body&amp;gt;&quot;, base_uri, unreachable_uri);&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;img나 기타 리소스들이 상대 경로로 놓여질 때 읽어올 base_uri, 에러가 났을때 알려줄 unreachable_uri가 추가된 것을 제외하면 특별한 것이 없습니다. 그리고 이 값들은 NULL로 넘겨도 상관없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;간단한 예제&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;여기까지 이야기한 것들을 바탕으로 가장 간단한 ewebkit 기반의 웹브라우저를 만들어보겠습니다.&lt;/p&gt;&lt;p&gt;https://github.com/ewebkit/samples/blob/master/devs/ryuan/simple.c&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;// gcc simplebutton.cpp `pkg-config --cflags --libs elementary ewebkit2`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;#include &amp;lt;Elementary.h&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;#include &amp;lt;EWebKit2.h&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;void on_done(void *userData, Evas_Object *webView, void *eventInfo)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_exit();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;EAPI_MAIN int&lt;br /&gt;elm_main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; ewk_init();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; Evas_Object* win;&lt;br /&gt;&amp;nbsp;&amp;nbsp; win = elm_win_add(NULL, &quot;sample&quot;, ELM_WIN_BASIC);&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_win_title_set(win, &quot;sample&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_smart_callback_add(win, &quot;delete,request&quot;, on_done, NULL);&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_win_autodel_set(win, EINA_TRUE);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; Evas_Object* bg = elm_bg_add(win);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_bg_color_set(bg, 0, 0, 255);&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_win_resize_object_add(win, bg);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_show(bg);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; Evas_Object* ewk = ewk_view_add(evas_object_evas_get(win));&lt;br /&gt;&amp;nbsp;&amp;nbsp; ewk_view_url_set(ewk, &quot;http://bunhere.tistory.com&quot;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_resize(ewk, 400, 400);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_move(ewk, 0, 0);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_show(ewk);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_resize(win, 400, 400);&lt;br /&gt;&amp;nbsp;&amp;nbsp; evas_object_show(win);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; elm_run();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; ewk_shutdown();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;ELM_MAIN()&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;실행 결과입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 402px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/26044846532731EB05&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F26044846532731EB05&quot; width=&quot;402&quot; height=&quot;429&quot; filename=&quot;Screenshot from 2014-03-18 02:32:31.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>개발</category>
      <category>EFL</category>
      <category>Webkit</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/417</guid>
      <comments>https://bunhere.tistory.com/417#entry417comment</comments>
      <pubDate>Fri, 14 Mar 2014 08:44:00 +0900</pubDate>
    </item>
    <item>
      <title>WebKit/efl 하면서 쓸 ctags 만들기</title>
      <link>https://bunhere.tistory.com/414</link>
      <description>&lt;p&gt;ctags -R --exclude=.git --exclude=Examples --exclude=LayoutTests --exclude=ManualTests --exclude=WebKitLibraries --exclude=build --exclude=PerformanceTests&amp;nbsp; --exclude=Tools --exclude=WebKit.xcworkspace --exclude=layout-test-results&amp;nbsp; --exclude=WebKitBuild&amp;nbsp; --exclude=Websites --exclude=Source/*/win --exclude=Source/*/mac --exclude=Source/*/wince --exclude=Source/*/blackberry --exclude=Source/*/mac --exclude=Source/WebKit/--exclude=*.html --exclude=*.js --exclude=*.pl --exclude=*.php .&lt;br /&gt;&lt;/p&gt;</description>
      <category>개발</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/414</guid>
      <comments>https://bunhere.tistory.com/414#entry414comment</comments>
      <pubDate>Tue, 17 Dec 2013 20:22:22 +0900</pubDate>
    </item>
    <item>
      <title>GCC options</title>
      <link>https://bunhere.tistory.com/336</link>
      <description>&lt;p&gt;&amp;lt;&amp;lt; 작성중 &amp;gt;&amp;gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;성능과 관련된 옵션들&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;-fno-rtti&lt;/b&gt; (runtime type information)&lt;/p&gt;&lt;p&gt;rtti는 아래와 같이 두가지 경우에 사용됩니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;- #include &amp;lt;typeinfo&amp;gt;&lt;/p&gt;&lt;p&gt;typeinfo(this).name()&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;class type_info {&lt;br /&gt;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; virtual ~type_info();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool operator==(const type_info&amp;amp; rhs) const;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool operator!=(const type_info&amp;amp; rhs) const;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int before(const type_info&amp;amp; rhs) const;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; const char* name(__type_info_node* __ptype_info_node = &amp;amp;__type_info_root_node) const;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; const char* raw_name() const;&lt;br /&gt;private:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void *_m_data;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; char _m_d_name[1];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;};&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;- dynamic_cast&lt;/p&gt;&lt;p&gt;성능에 영향을 줄 수 있으므로 -fno-rtti 를 주면 type_info가 생성되지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;-Os&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;-Os는 O2에 -falign-functions&amp;nbsp; -falign-jumps&amp;nbsp; -falign-loops -falign-labels&amp;nbsp; -freorder-blocks -freorder-blocks-and-partition -fprefetch-loop-arrays&amp;nbsp; -ftree-vect-loop-version 를 제거한 것과 같다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;p&gt;&lt;b&gt;-fprofile-generate, &lt;/b&gt;&lt;b&gt;-fprofile-use, &lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #660000;&quot;&gt;&lt;span class=&quot;option&quot;&gt;-fprofile-arcs&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;/pre&gt;&lt;br /&gt;참고자료 : http://blog.man7.org/2012/10/how-much-do-builtinexpect-likely-and.html&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;Linker options&lt;/span&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt; (-Wl&lt;/span&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;, ...)&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;--as-needed : &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://www.ubuntu.or.kr/viewtopic.php?p=70082&quot;&gt;http://www.ubuntu.or.kr/viewtopic.php?p=70082&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/336</guid>
      <comments>https://bunhere.tistory.com/336#entry336comment</comments>
      <pubDate>Thu, 5 Dec 2013 21:55:17 +0900</pubDate>
    </item>
    <item>
      <title>WebKit/Efl 빌드하기(우분투)</title>
      <link>https://bunhere.tistory.com/387</link>
      <description>&lt;p&gt;마지막 update : 2014-08-06 (우분투 13.10)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;webkit을 빌드할면 소스코드부터 받아야 합니다.&lt;/p&gt;&lt;p&gt;소스코드를 받는 방법은 svn을 이용하거나 git을 이용하면 됩니다.(&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://www.webkit.org/building/checkout.html&quot;&gt;http://www.webkit.org/building/checkout.html&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;&amp;nbsp;- &lt;b&gt;svn에서 받기 : svn checkout https://svn.webkit.org/repository/webkit/trunk WebKit&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;- &lt;b&gt;git에서 받기 : git clone git://git.webkit.org/WebKit.git&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;EFL latest 기반에서 빌드하려면 아래 &quot;최신 EFL을 사용하여 빌드하기&quot;를 참고하세요.&lt;br /&gt;&lt;/p&gt;&lt;strike&gt;&lt;/strike&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;* jhBuild를 사용하여 빌드하기&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;WebKit/EFL을 빌드하는 가장 쉬운 방법은 &lt;b&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;https://trac.webkit.org/wiki/EFLWebKit&quot;&gt;https://trac.webkit.org/wiki/EFLWebKit&lt;/a&gt; &lt;/b&gt;을 읽고 따라하는 것입니다.&lt;/p&gt;&lt;p&gt;하지만, 현재 EFL 1.8에 기반하고 있습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;간단히 요약하면&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. 관련 패키지 설치&lt;/b&gt;&lt;/p&gt;패키지를 설치하는 방법은 아래 스크립트를 실행하는 것입니다.(우분투만 지원)&lt;p&gt;./Tools/efl/install-dependencies&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;tt&gt;2. dependency 패키지 업데이트&lt;/tt&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;./Tools/Scripts/update-webkitefl-libs&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;3. 웹킷 빌드&lt;/b&gt;&lt;/p&gt;&lt;pre class=&quot;wiki&quot;&gt;&lt;p&gt;./Tools/Scripts/build-webkit --efl --cmakeargs=&quot;-DSHARED_CORE=ON&quot;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;(SHARED_CORE 옵션은 선택사항입니다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 11pt; color: rgb(0, 85, 255);&quot;&gt;* 최신 EFL을&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; color: rgb(0, 85, 255);&quot;&gt; 사용하여 빌드하기&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;(trunk build)&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;단, 위 방법은 jhbuild를 사용하여야 하기 때문에 최신 EFL을 사용해서 빌드할 수 없습니다.&lt;/p&gt;&lt;/pre&gt;** EFL이 /usr/elocal에 설치되어 있다고 가정하겠습니다.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;아래 환경 변수들을 세팅합니다. (prefix를 가정했기 때문입니다. 아래 내용을 아시면 적절히 수정하시면 됩니다.)&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;export LD_LIBRARY_PATH=/usr/elocal/lib:$LD_LIBRARY_PATH&lt;/p&gt;&lt;p&gt;export PKG_CONFIG_PATH=/usr/elocal/lib/pkgconfig:$LD_LIBRARY_PATH&lt;/p&gt;&lt;p&gt;export PATH=/usr/elocal/bin:$PATH&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;Ubuntu 12.10는 최신 libsoup이 제공되지 않습니다.&lt;p&gt;&amp;nbsp;libsoup을 설치합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;libsoup은 jhbuild에 있는 url을 통해 받으실 수 있습니다.&lt;/p&gt;&lt;p&gt;ftp://ftp.gnome.org/pub/gnome/sources/libsoup/2.42/libsoup-2.42.0.tar.xz&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;압축을 풀고, 폴더로 이동하여 아래 명령을 실행합니다.&lt;/p&gt;&lt;p&gt;./configure --without-gnome --disable-introspection --prefix=/usr/elocal&lt;/p&gt;&lt;p&gt;make -j4&lt;/p&gt;&lt;p&gt;sudo make install&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;이제 웹킷 폴더로 이동하여 build 폴더를 만들고 이동합니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;mkdir build &amp;amp;&amp;amp; cd build&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;빌드합니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;cmake .. -DPORT=Efl -DENABLE_ACCESSIBILITY=Off -DENABLE_BATTERY_STATUS=Off -DCMAKE_INSTALL_PREFIX=/usr/elocal&lt;br /&gt;&lt;/p&gt;&lt;p&gt;make -j4&lt;/p&gt;&lt;p&gt;sudo make install&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;(첨:&lt;/p&gt;&lt;p&gt;최신 EFL을 사용하신다면 gstreamer가 설치되어 있을 것입니다.&lt;/p&gt;&lt;p&gt;아니라면,  -DENABLE_VIDEO=OFF -DENABLE_VIDEO_TRACK=OFF -DENABLE_WEB_AUDIO=OFF 를 통해 VIDEO 관련 기능을 꺼주셔야 합니다.&lt;/p&gt;&lt;p&gt;gstreamer 빌드 관련해서는 &lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;&lt;/span&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://seoz.egloos.com/4002136&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;gstreamer 최신 버전 설치하기&lt;/span&gt;&lt;/a&gt;를 참조하시면 됩니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위에 몇가지 OFF한 옵션들을 모두 켜서 빌드하려면 atk(ENABLE_ACCESSIBILITY), e_dbus(ENABLE_BATTERY_STATUS)가 있어야 합니다.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;test browser&lt;/b&gt;&lt;/p&gt;&lt;p&gt;WebKit/Efl을 빌드하면 MiniBrowser라는 테스트 브라우저를 제공하고 있습니다.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;아래 명령으로 테스트 브라우저를 실행할 수 있습니다.&lt;br /&gt;&lt;/p&gt;./bin/MiniBrowser&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;wiki&quot;&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 11pt; color: rgb(0, 85, 255);&quot;&gt;* 최신 EFL을&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; color: rgb(0, 85, 255);&quot;&gt; 사용하여 빌드하기&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;(tarball)&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;최근부터 ewebkit의 tarball을 제공하기 시작했습니다.&lt;/p&gt;&lt;p&gt;현재 버전은 1.11 alpha입니다.&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://download.enlightenment.org/rel/libs/webkit-efl/&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;http://download.enlightenment.org/rel/libs/webkit-efl/&lt;/span&gt;&lt;/a&gt; 에서 받으실 수 있습니다.&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;(주의: 위에서 제공되는 압축 파일은 전체 소스를 가지고 있지 않고 ewebkit을 빌드하는데 필요한 파일들만을 담고 있습니다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;기본적으로는 위 trunk 빌드를 참고하시면 됩니다.&lt;/p&gt;&lt;p&gt;빌드할 때는 아래와 같이 적으시면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;cmake .. -DCMAKE_INSTALL_PREFIX=/usr/elocal&lt;/p&gt;&lt;p&gt;make -j4&lt;/p&gt;&lt;p&gt;sudo make install&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;trunk 빌드와의 차이는 EFL port가 기본이며 몇가지 옵션들이 자동으로 꺼집니다. (BATTERY_STATUS)&lt;/p&gt;</description>
      <category>개발</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/387</guid>
      <comments>https://bunhere.tistory.com/387#entry387comment</comments>
      <pubDate>Tue, 26 Nov 2013 22:05:24 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] Range based for loop</title>
      <link>https://bunhere.tistory.com/411</link>
      <description>&lt;p&gt;&lt;b&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/405&quot;&gt;&lt;span style=&quot;background-color: rgb(154, 165, 234);&quot;&gt;목차로 가기&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;개인적으로 공부한 내용들로, 내용이 완벽하지 않을 수 있습니다. 부족한 부분/틀린 부분에 대한 Comment 환영합니다.&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;- 업데이트&lt;/p&gt;&lt;p&gt;&amp;nbsp;* 박진수님이 지적해주신 오타 수정&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;C++11 에는 새로운 형태의 for loop인 range based for loop를 지원합니다.&lt;/p&gt;&lt;p&gt;이미 python같은 언어에서는 지원되던 기능이기도 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;python에서는 아래처럼 루프를 사용할 수 있었습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### python&lt;/p&gt;&lt;p&gt;peoples = ['ryuan', 'yesum',&amp;nbsp; 'w.third']&lt;br /&gt;for p in peoples:&lt;br /&gt;&amp;nbsp;&amp;nbsp; print 'people :', p&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이것을 c++에서 구현하려면 아래와 같이 해야 할 것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;vector&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; vector&amp;lt;string&amp;gt; s;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; s.push_back(&quot;ryuan&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; s.push_back(&quot;yesum&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; s.push_back(&quot;w.third&quot;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (vector&amp;lt;string&amp;gt;::iterator i = s.begin(); i != s.end(); ++i)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;people :&quot; &amp;lt;&amp;lt; *i &amp;lt;&amp;lt; endl;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;물론 &lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/406&quot;&gt;auto&lt;/a&gt;의 등장으로 for loop는 아래처럼 간단해질 수 있습니다.&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (auto i = s.begin(); i != s.end(); ++i) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;people :&quot; &amp;lt;&amp;lt; *i &amp;lt;&amp;lt; endl;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하지만, 만약 vector대신 2차원 배열로 바꾸려고 하면 어떻게 해야 할까요?&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; const char *s[3] = { &quot;ryuan&quot;, &quot;yesum&quot;, &quot;w.third&quot; };&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i != 3; ++i)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;people :&quot; &amp;lt;&amp;lt; s[i] &amp;lt;&amp;lt; endl;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제 range based for loop를 쓰면 아래와 같습니다.&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;br /&gt;&lt;/p&gt;&lt;p&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //const char *s[3] = { &quot;ryuan&quot;, &quot;yesum&quot;, &quot;w.third&quot; };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; vector&amp;lt;string&amp;gt; s;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; s.push_back(&quot;ryuan&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; s.push_back(&quot;yesum&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; s.push_back(&quot;w.third&quot;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (auto i : s)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;people :&quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; endl;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;vector를 쓰던, 배열을 쓰던 동일합니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;주의할 점은 range loop의 인자 i 는 반드시 loop안에서 선언되어야 한다는 점입니다. 만약 loop밖에서 선언하고 안에서 사용하지 않는다면 아래처럼 에러가 날 것입니다.(gcc)&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;range_for_loop.cpp: In function ‘int main()’:&lt;br /&gt;range_for_loop.cpp:10:12: error: found ‘:’ in nested-name-specifier, expected ‘::’&lt;br /&gt;range_for_loop.cpp:10:10: error: ‘i’ is not a class, namespace, or enumeration&lt;br /&gt;range_for_loop.cpp:10:15: error: expected ‘;’ before ‘)’ token&lt;br /&gt;range_for_loop.cpp:13:5: error: expected primary-expression before ‘return’&lt;br /&gt;range_for_loop.cpp:13:5: error: expected ‘;’ before ‘return’&lt;br /&gt;range_for_loop.cpp:13:5: error: expected primary-expression before ‘return’&lt;br /&gt;range_for_loop.cpp:13:5: error: expected ‘)’ before ‘return’&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그럼 만약, 내가 만든 클래스를 range based for loop로 사용하고자 한다면 어떻게 하면 될까요?&lt;/p&gt;&lt;p&gt;물론 이런 경우가 흔하진 않겠지만, 간단한 class를 만들어보도록 하겠습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;class IntList&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class Iterator {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Iterator(const IntList* p, int pos)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : m_p(p)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , m_pos(pos)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Range based for loop use below methods&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool operator!=(const Iterator&amp;amp; other) const { return m_pos != other.m_pos; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int operator*() const { return m_p-&amp;gt;get(m_pos); }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; const Iterator operator++()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //little bit tricky&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++m_pos;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return *this;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; const IntList* m_p;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m_pos;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IntList()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; 10; ++i) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_arr[i] = i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int get(int i) const { return m_arr[i]; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Iterator begin() const { return Iterator(this, 0); }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Iterator end() const { return Iterator(this, 10); }&lt;br /&gt;private:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m_arr[10];&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IntList list;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (auto i : list)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; std::cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;/p&gt;&lt;p&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;실제로 쓸모는 없지만, range based for loop 는 동작합니다.&lt;/p&gt;&lt;p&gt;결국,&lt;br /&gt;&lt;/p&gt;&lt;p&gt;begin(), end()를 제공하고, 이때 반환되는 iterator 클래스에서 operator++, operator*, operator!=을 구현하면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참조 : http://www.cplusplus.com/forum/beginner/99989/&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참조 : http://www.cprogramming.com/c++11/c++11-ranged-for-loop.html&lt;br /&gt;&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <category>C++11</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/411</guid>
      <comments>https://bunhere.tistory.com/411#entry411comment</comments>
      <pubDate>Wed, 13 Nov 2013 06:31:23 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] Move semantics</title>
      <link>https://bunhere.tistory.com/410</link>
      <description>&lt;p&gt;&lt;b&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/405&quot;&gt;&lt;span style=&quot;background-color: rgb(154, 165, 234);&quot;&gt;목차로 가기&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;개인적으로 공부한 내용들로, 내용이 완벽하지 않을 수 있습니다. 부족한 부분/틀린 부분에 대한 Comment 환영합니다.&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;C++11에서는 Move semantics라는 개념이 도입되었습니다. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;move semantics가 도입된 배경에 대해 이해하기 위해 아래 예제를 보도록 하겠습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Number&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; explicit Number(int i)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : m_number(new int(i))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;Number Constructor is called(&quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot;)&quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ~Number()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (m_number)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;Number Destructor is called(&quot; &amp;lt;&amp;lt; *m_number &amp;lt;&amp;lt; &quot;)&quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; delete m_number;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Number(const Number&amp;amp; rhs)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : m_number(new int(*rhs.m_number))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;Number copy constructor is called&quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void printValue(Number n) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;print &quot; &amp;lt;&amp;lt; *n.m_number &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int* m_number;&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Number one(1);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Number::printValue(one);&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;설명을 위해 의도적으로 m_number를 heap에 할당했습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위 예제를 실행하면 아래와 같은 결과가 나옵니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;Number Constructor is called(1)&lt;br /&gt;Number copy constructor is called&lt;br /&gt;print 1&lt;/p&gt;&lt;p&gt;Number Destructor is called(1)&lt;/p&gt;&lt;p&gt;Number Destructor is called(1)&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;printValue의 인자로 넘겨주는 과정에서 한번의 복사과정이 발생하게 됩니다. 불필요한 객체를 막기 위해 printValue를 아래와 같이 바꿀 수 있습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;static void printValue(const Number&amp;amp; n) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;print &quot; &amp;lt;&amp;lt; *n.m_number &amp;lt;&amp;lt; endl;&lt;/p&gt;&lt;p&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;핵심은 reference로 변경한 것입니다. (reference는 원본을 참조하므로 내부에서 수정을 못하도록 const를 붙여주어야 합니다.)&lt;/p&gt;&lt;p&gt;이제 복사 생성자(copy constructor)가 호출되지 않을 것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제 예제를 좀 더 확장해 아래와 같은 경우를 보도록 하겠습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;// in main&lt;/p&gt;&lt;p&gt;Number x(one); // (1)&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;이 경우 x와 one은 별도의 객체이므로 복사 생성자가 불려야 합니다.&lt;/p&gt;&lt;br /&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;class Number {&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Number operator+(Number&amp;amp; rhs)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Number(m_number + rhs.m_number);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;&lt;/p&gt;&lt;p&gt;};&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Number make_number()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Number(2);&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;&lt;br /&gt;//in main&lt;br /&gt;Number value(make_number()); // (2)&lt;br /&gt;Number sum(one + two); // (3)&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;value와 sum을 만들기 위해서는 모두 두번의 복사 생성자가 불립니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 경우에 불리는 복사 생성자는 사실상&amp;nbsp; 불필요합니다. 하지만 제거할 방법은 마땅하지 않습니다.&lt;/p&gt;&lt;p&gt;물론 일부 compiler에서 최적화를 지원합니다. (Return Value Optimization : RVO)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;gcc 의 경우 -fno-elide-constructors 를 사용하면 이 기능을 끌 수 있습니다.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;현재 예제의 경우는 간단하기 때문에 임시로 생성되는 객체들에 대한 부담이 적을 수 있습니다만, Number가 아니라 Vector와 같은 많은 리소스를 사용해야 하는 경우라면 이것은 그대로 비효율이 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;(1)과 (2), (3)에는 한가지 중요한 차이점이 있습니다.&lt;/p&gt;&lt;p&gt;(1)은 lvalue를 받은 경우이고, (2), (3)은 rvalue를 넘겨받은 경우라는 사실입니다.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;c++11부터는 이동 생성자가 생겼습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/409&quot;&gt;rvalue reference&lt;/a&gt;를 인자로 받는 새로운 생성자입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위 예제에서 아래와 같이 이동 생성자를 추가하겠습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Number(Number&amp;amp;&amp;amp; rhs)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;Number move constructor is called&quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_number = rhs.m_number;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rhs.m_number = nullptr;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;이동 생성자가 복사 생성자와 다른 점은 rvalue reference로 받아서 받은 rhs의 m_number를 그대로 사용한다는 점입니다.&lt;/p&gt;&lt;p&gt;따라서, 복사 생성자가 불렸을 때와 비교해 불필요한 메모리 할당/해제가 사라지게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참조 : http://stackoverflow.com/questions/3106110/what-is-move-semantics&lt;br /&gt;&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <category>C++11</category>
      <category>move semantics</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/410</guid>
      <comments>https://bunhere.tistory.com/410#entry410comment</comments>
      <pubDate>Sun, 10 Nov 2013 17:37:06 +0900</pubDate>
    </item>
    <item>
      <title>[c++11] rvalue reference</title>
      <link>https://bunhere.tistory.com/409</link>
      <description>&lt;p&gt;&lt;b&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/405&quot;&gt;&lt;span style=&quot;background-color: rgb(154, 165, 234);&quot;&gt;목차로 가기&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;개인적으로 공부한 내용들로, 내용이 완벽하지 않을 수 있습니다. 부족한 부분/틀린 부분에 대한 Comment 환영합니다.&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이미 C++&amp;nbsp; 에서는 Reference(참조자)를 지원하고 있습니다.rvalue Reference를 설명하기 전에 기존의 Reference의 예제를 잠깐 살펴보겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int zero = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;amp; a = zero; //OK&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;amp; b = 0; // Compile Error&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아시겠지만, Reference에 0을 할당하는 것은 불가능합니다.&lt;/p&gt;&lt;p&gt;예제를 컴파일 해보면 아래와 같은 에러를 볼 수 있습니다. (gcc 기준)&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;g++ rvalue_reference.cpp &lt;br /&gt;rvalue_reference.cpp: In function ‘int main()’:&lt;br /&gt;rvalue_reference.cpp:8:14: error: invalid initialization of non-const reference of type ‘int&amp;amp;’ from an rvalue of type ‘int’&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;에러 메시지를 번역해보자면,&quot;int 타입의 rvalue에서 int&amp;amp; 타입인 non-const reference로의&amp;nbsp; 잘못된 초기화&quot; 입니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;물론 const int&amp;amp; b 로 바꿔도 동작은 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;여기서 핵심은 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;1. 0은 rvalue입니다.&lt;/p&gt;&lt;p&gt;2. (기존의) reference는 rvalue를 참조하지 못합니다. (const reference(&amp;amp;)는 rvalue도 담을순 있습니다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;따라서 reference(&amp;amp;)를 lvalue reference라고 부를 수 있습니다. (물론 그동안 이렇게 부를 필요가 없었죠. rvalue reference가 나오기 전까진...)&lt;br /&gt;&lt;/p&gt;&amp;nbsp;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;lvalue 와 rvalue&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제 lvalue와 rvalue에 대해 이야기해보겠습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;전통적인 의미로 이것은 Left Value와 Right Value를 의미했으나(참조1),&lt;/p&gt;&lt;p&gt;사실상 C에서의 lvalue는 수식의 오른쪽 값이 쓰여질 수 있는 메모리 공간을 가르키는 용어(locater value)입니다.&lt;br /&gt;(오른쪽 값이 rvalue를 의미하는 것은 아닙니다.)&lt;/p&gt;&lt;br /&gt;따라서 lvalue는 반드시 left에 올 필요는 없습니다.&lt;br /&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;int x = 9;&lt;/p&gt;&lt;p&gt;std::string s;&lt;/p&gt;&lt;p&gt;int* p = 0;&lt;/p&gt;&lt;p&gt;int&amp;amp; ri = x;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;x, s, p, ri 모두 lvalue입니다. 4번 라인에서 x는 오른쪽에도 존재합니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제 lvalue를 다시 설명해보고자 합니다.&lt;/p&gt;&lt;p&gt;&quot;lvalue란 이름은 E1 = E2 의 수식에서 E1이 (수정 가능한) lvalue 이어야 한다는 데서 기원하고 있습니다. 그러나 &quot;locaor value&quot;를 의미한다고 생각하는 것이 나을 것입니다.&quot;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The
 name &quot;lvalue&quot; comes originally from the assignment expression E1 = E2, 
in which the left operand E1 must be a (modifiable) lvalue. It is 
perhaps better considered as representing an object &quot;locator value.&quot;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;rvalue는 수식의 값으로써 종종 언급되었습니다.&lt;p&gt;What is sometimes called
  ‘‘rvalue’’ is in this International
  Standard described as the ‘‘value of
  an expression’’.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;rvalue의 대표적인 예는 literal들입니다. 위 예제의 9나 0 또는 'a', &quot;hello&quot;는 rvalue들입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;아래의 예를 더 보도록 하겠습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;br /&gt;++i;&lt;br /&gt;i++;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;++i는 lvalue이고 i++은 rvalue입니다.&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;i++이 rvalue인 것을 증명하기 위해, 간단한 테스트를 해보겠습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;###c++&lt;/p&gt;&lt;p&gt;int i = 1;&lt;br /&gt;int&amp;amp; a = ++i; // ok&lt;br /&gt;int&amp;amp; b = i++; // compile error&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;4번 라인은 앞에서 봤던 것과 동일한 에러가 날 것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;앞서 ++i는 lvalue인 i의 값을 증가시킨 후, i를 반환합니다. 따라서 ++i는 lvalue입니다.&lt;/p&gt;&lt;p&gt;반면, i++은 lvalue인 i의 값을 증가시키지만, 증가되기 전의 값을 임시로 보관하여 반환합니다.&lt;/p&gt;&lt;p&gt;따라서, 반환되는 값은 임시로 존재하며 수식이 끝나는 순간 사라지게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또 다른 예를 보겠습니다.&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;int i = 1;&lt;br /&gt;const int&amp;amp; p = i;&lt;/p&gt;&lt;p&gt;p = 7; // compile error&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;p 는 lvalue이지만, const 속성때문에 rvalue인 7을 저장할 수 없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;lvalue나 rvalue 모두 const 나 non-const 속성을 가질 수 있습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;string one(&quot;one&quot;);&lt;br /&gt;const string two(&quot;two&quot;);&lt;br /&gt;string three() { return &quot;three&quot;; }&lt;br /&gt;const string four() { return &quot;four&quot;; }&lt;/p&gt;&lt;p&gt;static int s_five = 0;&lt;/p&gt;&lt;p&gt;int&amp;amp; five() { return s_five; }&lt;br /&gt;&lt;/p&gt;&lt;p&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; one;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 변경 가능한(non-const)lvalue&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; two;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 변경 불가능한(const) lvalue&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; three(); // 변경 가능한(non-const) rvalue&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; four();&amp;nbsp; // 변경 불가능한(const) rvalue&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;amp; f = five(); // 변경 가능한(non-const)lvalue&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; f = 5;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; f &amp;lt;&amp;lt; &quot; equals &quot; &amp;lt;&amp;lt; s_five &amp;lt;&amp;lt; endl;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;앞에서 보여드린 것처럼 reference는 lvalue를 참조합니다.&lt;/p&gt;&lt;p&gt;따라서 reference를 반환하는 five도 lvalue입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;수식(expression)이 끝나도 존재하는 것을 lvalue, 수식의 종료와 함께 사라지는 임시적인 값을 rvalue라고 설명하기도 합니다.&lt;/p&gt;&lt;p&gt;또 다른 설명으로 수식(expression)에서 identity를 가지는 value가 lvalue, identity를 가지지 않는 value가 rvalue라고도 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;여기까지가 C++ 03까지에 대한 내용입니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제 rvalue reference에 대해 설명하도록 하겠습니다.&lt;/p&gt;&lt;p&gt;c++11에서는 rvalue reference(&amp;amp;&amp;amp;)라는 새로운 operator가 등장합니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;int&amp;amp;&amp;amp; sum(int a, int b)&lt;br /&gt;{&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return a + b;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;amp;&amp;amp; r = sum(1, 2);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; r &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;크게 필요성을 느끼기 어려운 예제입니다. 심지어 gcc에서는 warning도 납니다. 하지만 짚고 넘어갈 부분이 있습니다.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;보시면 a + b의 결과가 문장(8 line)이 지나갈때까지 살아있게 됩니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;rvalue인 a + b는 해당 수식이 소멸되는 시점에 사라져야 하지만, rvalue reference로 참조하게 되면 lifetime이 연장되어 존재하게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이러한 value 유형을 xvalue (&quot;eXpiring&quot; value) 라고 합니다. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;xvalue는 lvalue처럼 identity를 갖지만 추가로 movability를 갖습니다.&lt;/p&gt;&lt;p&gt;lifetime이 끝나도 identity가 유지되는 한 존재하게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;(기존의) lvalue와 xvalue를 묶어서 glvalue(&quot;generalized&quot; lvalue) 라고 부릅니다.&lt;/p&gt;&lt;p&gt;glvalue는 identity가 있다는 특징이 있습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;기존의 rvalue는 임시적이고 identity를 갖지 않지만, xvalue가 등작했기 때문에 xvalue까지를 포함하여 rvalue라고 합니다.&lt;/p&gt;&lt;p&gt;대신 xvalue가 아닌 rvalue들을 prvalue (pure rvalue) 라고 부릅니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 365px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/27442137527E06AD0E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F27442137527E06AD0E&quot; width=&quot;365&quot; height=&quot;251&quot; filename=&quot;YKlod.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;rvalue reference의 진정한 가치를 알려면 move semantics에 대해 이해해야 합니다.&lt;/p&gt;&lt;p&gt;move semantics에 대해서는 다음 글에서 이야기하려고 합니다.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참조1 (The main fatures of CPL) : http://comjnl.oxfordjournals.org/content/6/2/134.full.pdf+html&lt;/p&gt;&lt;p&gt;참조 2 : http://blog.smartbear.com/development/c11-tutorial-explaining-the-ever-elusive-lvalues-and-rvalues/&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참조 : http://scor7910.tistory.com/66&lt;/p&gt;&lt;p&gt;참조 : http://en.wikipedia.org/wiki/Rvalue_reference#rvalue_reference&lt;/p&gt;&lt;p&gt;참조 : http://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues&lt;/p&gt;&lt;p&gt;참조 : http://stackoverflow.com/questions/371503/why-is-i-considered-an-l-value-but-i-is-not&lt;/p&gt;&lt;p&gt;참조 : http://c0x.coding-guidelines.com/6.3.2.1.html&lt;/p&gt;&lt;p&gt;참조 : https://prog.woong.org/11&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <category>C++11</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/409</guid>
      <comments>https://bunhere.tistory.com/409#entry409comment</comments>
      <pubDate>Thu, 7 Nov 2013 23:12:23 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] Variadic template</title>
      <link>https://bunhere.tistory.com/408</link>
      <description>&lt;div id=&quot;content&quot;&gt;&lt;div class=&quot;entry&quot;&gt;&lt;div class=&quot;article&quot;&gt;&lt;b&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/405&quot;&gt;&lt;span style=&quot;background-color: rgb(154, 165, 234);&quot;&gt;목차로 가기&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;div class=&quot;tt_article_useless_p_margin&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;개인적으로 공부한 내용들로, 내용이 완벽하지 않을 수 있습니다. 부족한 부분/틀린 부분에 대한 Comment 환영합니다.&amp;gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;먼저 짧은 영어 탓에 variadic이라는 단어부터 찾아봤습니다.&lt;/p&gt;&lt;p&gt;하지만, variadic이란 단어는 원래 존재했던 단어는 아닌듯 합니다. (&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://en.wiktionary.org/wiki/variadic&quot;&gt;http://en.wiktionary.org/wiki/variadic&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;어원은 variable 과 -adic 이 결합된 단어라고 하며, `임의의 많은 변수를 취하는` 이란 뜻입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;C언어를 접해서 쓰고 있는 사람이라면 printf를 생각하면 쉬울 듯 합니다.&lt;/p&gt;&lt;p&gt;printf는 대표적인&amp;nbsp; variadic function입니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;// printf의 선언&lt;/p&gt;&lt;p&gt;int printf(const char *format, ...);&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Variadic Template을 지원한다는 것은 결국 임의의 많은 template parameter를 취하는 템플릿을 지원한다는 것을 의미합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;기본적인 모양은 아래와 같습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;template&amp;lt;typename ... Values&amp;gt; class tuple;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;(코딩 스타일은 어떻게 하는 것이 좋은지 모르겠네요. ... (ellipse operator) 과 typename, Values사이에는&amp;nbsp; space가 있어도 되고 없어도 되는듯 합니다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;인스턴스를 만들때는 아래처럼 쓰게 됩니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;// 세개의 template 인자를 갖는 some_instance_name&lt;br /&gt;&lt;/p&gt;&lt;p&gt;tuple&amp;lt;int, std::vector&amp;lt;int&amp;gt;, std::map&amp;lt;std::string, std::vector&amp;lt;int&amp;gt;&amp;gt;&amp;gt; some_instance_name;&lt;/p&gt;&lt;p&gt;//인자의 개수가 0개여도 괜찮습니다.&lt;/p&gt;&lt;p&gt;tuple&amp;lt;&amp;gt; a;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;몇개의 인자를 제한하고자 하면 아래와 같이 해당하는 인자들뒤에 typename ... values 를 적으면 됩니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;template&amp;lt;typename T, typename ... Values&amp;gt; class tuple;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;간단한 예제를 만들어봤습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class dog {&lt;br /&gt;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void speak() const { cout &amp;lt;&amp;lt; &quot;bow wow&quot; &amp;lt;&amp;lt; endl; }&lt;br /&gt;};&lt;br /&gt;class cat {&lt;br /&gt;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void speak() const { cout &amp;lt;&amp;lt; &quot;meow&quot; &amp;lt;&amp;lt; endl; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &amp;lt;typename T&amp;gt;&lt;br /&gt;void speak(const T&amp;amp; p)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p.speak();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template &amp;lt;typename T, typename ... ARGS&amp;gt;&lt;br /&gt;void speak(const T&amp;amp; p, ARGS ... args)&lt;br /&gt;{&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p.speak();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; speak(args...);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dog a, b, c, d;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cat e, f, g, h;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; speak(a, e, b, f, c, g, d, h);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;좀 억지스러운 면이 있네요(굳이 이렇게 어렵게 짤 필요는 없어보입니다.).&lt;/p&gt;&lt;p&gt;적절한 사용법은 찾아야 될듯 합니다.(실제웹킷에서 쓰는 예를&amp;nbsp; 아래에 첨부했습니다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;어쨌든 30라인의 speak라는 함수는 dog객체와 cat객체를 임의의 개수만큼 받을 수 있도록 되어 있습니다.이를 위해 두가지 버전의 speak함수를 구현했습니다. (13-17라인, 19-24라인)&lt;/p&gt;&lt;p&gt;19-24라인의 speak는 variadic template으로 구현되어 있습니다. 이 버전의 speak를 보면, 첫번째 템플릿 인자는 T로 받아서(19라인) speak()를 호출합니다. (22라인), 그리고 나머지 인자들은 args... 이용해 speak를 다시 호출합니다. (23라인)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;즉, 재귀적으로 variadic template 메소드를 호출하다가 마지막으로 인자가 한개만 남게 되면 13-17라인의 speak 함수를 통해 출력하게 됩니다. 이런 형태의 template을 recursive template이라고 합니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;만약 13-17라인의 speak 함수가 없다면, 컴파일 타임에 아래와 같은 에러를 출력하게 됩니다.(gcc)&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;variadic_template.cpp: In instantiation of ‘void speak(const T&amp;amp;, ARGS ...) [with T = cat; ARGS = {}]’:&lt;br /&gt;variadic_template.cpp:18:5:&amp;nbsp;&amp;nbsp; recursively required from ‘void speak(const T&amp;amp;, ARGS ...) [with T = cat; ARGS = {dog, cat, dog, cat, dog, cat}]’&lt;br /&gt;variadic_template.cpp:18:5:&amp;nbsp;&amp;nbsp; required from ‘void speak(const T&amp;amp;, ARGS ...) [with T = dog; ARGS = {cat, dog, cat, dog, cat, dog, cat}]’&lt;br /&gt;variadic_template.cpp:25:33:&amp;nbsp;&amp;nbsp; required from here&lt;br /&gt;variadic_template.cpp:18:5: error: no matching function for call to ‘speak()’&lt;br /&gt;variadic_template.cpp:18:5: note: candidate is:&lt;br /&gt;variadic_template.cpp:15:6: note: template&amp;lt;class T, class ... ARGS&amp;gt; void speak(const T&amp;amp;, ARGS ...)&lt;br /&gt;variadic_template.cpp:15:6: note:&amp;nbsp;&amp;nbsp; template argument deduction/substitution failed:&lt;br /&gt;variadic_template.cpp:18:5: note:&amp;nbsp;&amp;nbsp; candidate expects 2 arguments, 0 provided&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;유사한 예제로, Dog객체와 Cat 객체가 순서대로 있어야 하는 speak를 아래와 같이 만들수도 있습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;template &amp;lt;class Dog, class Cat&amp;gt;&lt;br /&gt;void speak(const Dog&amp;amp; d, const Cat&amp;amp; c)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; d.speak();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template &amp;lt;class Dog, class Cat, class ... ARGS&amp;gt;&lt;br /&gt;void speak(const Dog&amp;amp; d, const Cat&amp;amp; c, ARGS ... args)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; d.speak();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; speak(args...);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dog a, b, c, d;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cat e, f, g, h;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; speak(a, e, b, f, c, g, d, h);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //speak(e, b, f, c, g, d, h); //Compile Error!&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;이렇게&amp;nbsp; 일부 인자만을 지정하는 것을 partial specialization이라고 부르기도 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;ellipse operator&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;보신 바와 같이, ellipse operator(...)는 크게 두가지 형태로 사용됩니다. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;첫번째로, template parameter list나 speak()와 같이 template body의 인자 목록에서 사용될 경우 parameter pack을 선언한다고 합니다. (전자의 경우 template parameter pack, 후자의 경우 function parameter pack)&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;// template parameter pack&lt;br /&gt;type ... Args&lt;br /&gt;typename|class ... Args&lt;br /&gt;template &amp;lt; parameter-list &amp;gt; ... Args&lt;br /&gt;&lt;br /&gt;// function parameter pack&lt;br /&gt;Args ... args&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;결국 parameter pack 을 가지는 template이 Variadic template이라고 할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;두번째로, spack()의 body에서 사용된 것처럼 (args ... ) ellipse operator 가 템플릿 또는 함수 호출 인자의 오른쪽에 나오는 경우, parameter pack은 unpack한다 또는 확장(expansion)한다고 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위 예제에서는 간단한 형태의 parameter pack expansion 을 보여드렸습니다. (args ... )&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하지만, expansion이 어디서 일어나느냐에 따라 다양한 형태로 이뤄지게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;확장이 이뤄질 수 있는 곳들은 다음과 같습니다. (아래 참조에 있는 것들을 가져왔습니다.)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Function Argument list&lt;/b&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;f(&amp;amp;args...); // expands to f(&amp;amp;E1, &amp;amp;E2, &amp;amp;E3)&lt;br /&gt;f(n, ++args...); // expands to f(n, ++E1, ++E2, ++E3);&lt;br /&gt;f(++args..., n); // expands to f(++E1, ++E2, ++E3, n);&lt;br /&gt;f(const_cast&amp;lt;const Args*&amp;gt;(&amp;amp;args)...);&lt;br /&gt;// f(const_cast&amp;lt;const E1*&amp;gt;(&amp;amp;X1), const_cast&amp;lt;const E2*&amp;gt;(&amp;amp;X2), const_cast&amp;lt;const E3*&amp;gt;(&amp;amp;X#)&lt;br /&gt;f(h(args...) + args...); // expands to &lt;br /&gt;// f(h(E1,E2,E3) + E1, h(E1,E2,E3) + E2, h(E1,E2,E3) + E3)&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Template Argument list&lt;/b&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;template&amp;lt;class A, class B, class...C&amp;gt; void func(A arg1, B arg2, C...arg3)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; container&amp;lt;A,B,C...&amp;gt; t1;&amp;nbsp; // expands to container&amp;lt;A,B,E1,E2,E3&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; container&amp;lt;C...,A,B&amp;gt; t2;&amp;nbsp; // expands to container&amp;lt;E1,E2,E3,A,B&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; container&amp;lt;A,C...,B&amp;gt; t3;&amp;nbsp; // expands to container&amp;lt;A,E1,E2,E3,B&amp;gt; &lt;br /&gt;}&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Template Parameter list&lt;/b&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;template&amp;lt;typename... T&amp;gt; struct value_holder&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; template&amp;lt;T... Values&amp;gt; // expands to a non-type template parameter &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct apply { };&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // list, such as &amp;lt;int, char, int(&amp;amp;)[5]&amp;gt;&lt;br /&gt;};&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;sizeof operator&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;template&amp;lt;class... Types&amp;gt;&lt;br /&gt;struct count {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static const std::size_t value = sizeof...(Types);&lt;br /&gt;};&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;만약 count&amp;lt;int, char&amp;gt; 이면&amp;nbsp; value는 2가 될 것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Initializer list of array&lt;/b&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;template&amp;lt;typename... Ts&amp;gt; void func(Ts... args){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; const int size = sizeof...(args) + 2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int res[size] = {1,args...,2};&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Member initializer list&lt;/b&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;template&amp;lt;class... Mixins&amp;gt;&lt;br /&gt;class X : public Mixins... {&lt;br /&gt;&amp;nbsp;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; X(const Mixins&amp;amp;... mixins) : Mixins(mixins)... { }&lt;br /&gt;};&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;struct a1{};&lt;br /&gt;struct a2{};&lt;br /&gt;struct a3{};&lt;br /&gt;struct a4{};&lt;br /&gt;&lt;br /&gt;template&amp;lt;class X&amp;gt; struct baseC{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; baseC(int a) {printf(&quot;baseC primary ctor: %d\n&quot;, a);}&lt;br /&gt;};&lt;br /&gt;template&amp;lt;&amp;gt; struct baseC&amp;lt;a1&amp;gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; baseC(int a) {printf(&quot;baseC a1 ctor: %d\n&quot;, a);}&lt;br /&gt;};&lt;br /&gt;template&amp;lt;&amp;gt; struct baseC&amp;lt;a2&amp;gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; baseC(int a) {printf(&quot;baseC a2 ctor: %d\n&quot;, a);}&lt;br /&gt;};&lt;br /&gt;template&amp;lt;&amp;gt; struct baseC&amp;lt;a3&amp;gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; baseC(int a) {printf(&quot;baseC a3 ctor: %d\n&quot;, a);}&lt;br /&gt;};&lt;br /&gt;template&amp;lt;&amp;gt; struct baseC&amp;lt;a4&amp;gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; baseC(int a) {printf(&quot;baseC a4 ctor: %d\n&quot;, a);}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template&amp;lt;class...A&amp;gt; struct container : public baseC&amp;lt;A&amp;gt;...{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; container(): baseC&amp;lt;A&amp;gt;(12)...{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf(&quot;container ctor\n&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main(void){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; container&amp;lt;a1,a2,a3,a4&amp;gt; test;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;lamda captures&lt;/b&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;template&amp;lt;class ...Args&amp;gt;&lt;br /&gt;void f(Args... args) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; auto lm = [&amp;amp;, args...] { return g(args...); };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; lm();&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Exception specification list&lt;/b&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;template&amp;lt;class...X&amp;gt; void func(int arg) throw(X...)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;// ... throw different Xs in different situations&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래 link는 webkit에서 아직 공식 지원되지 않는 make_unique를 내부적으로 만들어서 쓰기 위해 variadic template 버전과 variadic template이 지원되지 않는 버전을 같이 만든 패치입니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://trac.webkit.org/changeset/156000&quot;&gt;http://trac.webkit.org/changeset/156000&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참조: &lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Variadic_templates&quot;&gt;http://en.wikipedia.org/wiki/Variadic_templates&lt;/a&gt;&lt;/p&gt;&lt;p&gt;참조2 : &lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://en.cppreference.com/w/cpp/language/parameter_pack&quot;&gt;http://en.cppreference.com/w/cpp/language/parameter_pack&lt;/a&gt;&lt;/p&gt;&lt;p&gt;참조3 : &lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://pic.dhe.ibm.com/infocenter/lnxpcomp/v111v131/index.jsp?topic=%2Fcom.ibm.xlcpp111.linux.doc%2Flanguage_ref%2Fvariadic_templates.html&quot;&gt;http://pic.dhe.ibm.com/infocenter/lnxpcomp/v111v131/index.jsp?topic=%2Fcom.ibm.xlcpp111.linux.doc%2Flanguage_ref%2Fvariadic_templates.html&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <category>C++0x</category>
      <category>C++11</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/408</guid>
      <comments>https://bunhere.tistory.com/408#entry408comment</comments>
      <pubDate>Wed, 6 Nov 2013 20:17:29 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] unique_ptr</title>
      <link>https://bunhere.tistory.com/407</link>
      <description>&lt;div id=&quot;content&quot;&gt;&lt;div class=&quot;entry&quot;&gt;&lt;div class=&quot;article&quot;&gt;&lt;b&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/405&quot;&gt;&lt;span style=&quot;background-color: rgb(154, 165, 234);&quot;&gt;목차로 가기&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;div class=&quot;tt_article_useless_p_margin&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;개인적으로 공부한 내용들로, 내용이 완벽하지 않을 수 있습니다. 부족한 부분/틀린 부분에 대한 Comment 환영합니다.&amp;gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;unique_ptr는 C++에서 제공하는 스마트 포인터입니다.&lt;/p&gt;&lt;p&gt;(TODO: 스마트 포인터에 대한 설명 추가)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;unique_ptr를 사용하면 동적으로 힙 영역에 할당된 인스턴스에 대한 소유권을 얻고 unique_ptr 객체가 사라지면 해당 인스턴스를 해제하게 됩니다.&lt;/p&gt;&lt;p&gt;소유권을 갖기 때문에 인스턴스를 소유하는 unique_ptr은 동시에 두개가 되어선 안됩니다.&lt;/p&gt;&lt;p&gt;(둘이 된 경우 소멸되는 과정에서 double free 에러가 발생하게 될 것입니다.)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;unique_ptr를 사용하려면 &amp;lt;memory&amp;gt; 헤더를 인클루드하면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;간단한 unique_ptr의 사용 예제입니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;memory&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;void f()&lt;br /&gt;{&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unique_ptr&amp;lt;int&amp;gt; a(new int(3));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; *a.get() &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; f();&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;a는 f()함수가 사라짐과 동시에 소멸됩니다. 사용자가 굳이 delete를 해줄 필요가 없고 unique_ptr&amp;lt;int&amp;gt; 객체인 a가 자신의 소멸 시점에&amp;nbsp; 할당된 메모리를 제거할 것입니다.&lt;/p&gt;&lt;p&gt;예제에서는 unique_ptr의 메소드중 하나인 get()을 이용해 할당된 메모리를 얻어 출력하고 있습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;a를 선언하는 방법은 아래와 같이 할 수도 있습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;unique_ptr&amp;lt;int&amp;gt; a = unique_ptr&amp;lt;int&amp;gt;(new int(3));&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래와 같이 사용하는 것도 가능합니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;br /&gt;unique_ptr&amp;lt;int&amp;gt; factory()&lt;br /&gt;{&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return unique_ptr&amp;lt;int&amp;gt;(new int(3));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void f()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unique_ptr&amp;lt;int&amp;gt; a = factory();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; *a.get() &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;하지만, 아래와 같이 대입을 하는 것은 불가능합니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;unique_ptr&amp;lt;int&amp;gt; a = unique_ptr&amp;lt;int&amp;gt;(new int(3));&lt;br /&gt;unique_ptr&amp;lt;int&amp;gt; b = a; // error!!&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 경우 아래와 같은 에러가 발생합니다. (gcc 기준)&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;$ g++ unique_ptr.cpp -std=c++11&lt;br /&gt;unique_ptr.cpp: In function ‘void f()’:&lt;br /&gt;unique_ptr.cpp:14:25: error: use of deleted function ‘std::unique_ptr&amp;lt;_Tp, _Dp&amp;gt;::unique_ptr(const std::unique_ptr&amp;lt;_Tp, _Dp&amp;gt;&amp;amp;) [with _Tp = int; _Dp = std::default_delete&amp;lt;int&amp;gt;; std::unique_ptr&amp;lt;_Tp, _Dp&amp;gt; = std::unique_ptr&amp;lt;int&amp;gt;]’&lt;br /&gt;In file included from /usr/include/c++/4.7/memory:86:0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from unique_ptr.cpp:2:&lt;br /&gt;/usr/include/c++/4.7/bits/unique_ptr.h:262:7: error: declared here&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;std::move&lt;/b&gt;&lt;/p&gt;&lt;p&gt;데이터를 이동시키고자 할때는 아래 예제처럼 std::move를 사용해야 합니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;void f()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unique_ptr&amp;lt;int&amp;gt; a(new int(3));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unique_ptr&amp;lt;int&amp;gt; b = move(a);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; *b.get() &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //cout &amp;lt;&amp;lt; *a.get() &amp;lt;&amp;lt; endl; //Segmentation Fault!&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;move를 호출하면 a가 소유하고 있는 객체(new int(3))는 b에게 넘어갑니다. 따라서 a는 empty 상태가 되고 이러한 a를 통한 접근은 segmentation fault를 야기하게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위에서 간단히 int를 할당하여 int의 raw pointer를 얻는 법을 계속 보여드렸습니다. 하지만 이런 접근은 그다지 안전하다고 볼 수 없습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;unique_ptr에 객체를 할당하고 객체의 메소드를 사용하는 것이 더 일반적인 사용법이라고 생각됩니다. 이 때는 기존에 직접 할당했을 때와 마찬가지로 -&amp;gt;를 사용하여 접근할 수 있습니다. 간단한 예제를 만들어보았습니다.&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;memory&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;class house&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; house(int window, int door) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : m_window(window)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , m_door(door)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int window() const { return m_window; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int door() const { return m_door; }&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m_window;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m_door;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unique_ptr&amp;lt;house&amp;gt; home(new house(4, 1));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; home-&amp;gt;window() &amp;lt;&amp;lt; &quot; windows and &quot; &amp;lt;&amp;lt; home-&amp;gt;door() &amp;lt;&amp;lt; &quot; doors&quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;home은 house의 객체가 아니라 unique_ptr&amp;lt;house&amp;gt;의 객체입니다. 하지만 window()나 door()와 같은 house의 메소드에 접근할 수 있습니다. (사실은 unique_ptr이 -&amp;gt;를 오버라이드하는 것으로 보는 것이 더 정확합니다.)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;std::unqie_ptr::reset&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;만약 unique_ptr에 할당된 값을 지우거나 다른 값으로 바꾸고 싶다면 reset이란 메소드를 사용하면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위 예제에서 main부분만을 아래와 같이 변경해보겠습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;int main()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unique_ptr&amp;lt;house&amp;gt; home; //empty&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; home.reset(new house(2, 1));&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; home.reset(new house(4, 1));&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; home.reset();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; home.reset(); //nothing happend&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;} &lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;home 객체는 empty 로 생성되었습니다. 하지만 5번 reset을 통해 house(2, 1)의 ownership을 갖게 됩니다.&lt;/p&gt;&lt;p&gt;6번 reset을 수행하면 위에서 생성된 house(2,1)은 소멸되고 house(4, 1)의 ownership을 갖게 됩니다.&lt;/p&gt;&lt;p&gt;7번 라인과 같이 인자 없이 수행하면 갖고 있는 객체를 소멸시키게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 동작은 9번 라인과 같이 현재 객체가 없는 경우에도 아무런 문제가 없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;std::unique_ptr::release&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;현재 소유한 인스턴스의 소유권을 해제 없이 놓고자 할때는 release라는 메소드를 사용합니다.&lt;/p&gt;&lt;p&gt;이 경우, 반환된 인스턴스를 직접 해제해 주어야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;만약 현재 unique_ptr객체가 empty였다면, 반환된 인스턴스는 nullptr이 될 것입니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unique_ptr&amp;lt;house&amp;gt; home; //empty&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; house *p = home.release();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (p)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;It's not printed&quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; home.reset(new house(4, 1));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p = home.release();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (p) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;p should be released&quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; delete p;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;custom deleter&lt;/b&gt;&lt;/p&gt;&lt;p&gt;이미 알고 계시겠지만, unique_ptr은 메모리의 할당에는 관여하지 않으면서 메모리의 해제를 수행합니다, 따라서 만약 
메모리를 new가 아니라 malloc과 같이 다른 형태로 할당했다면 문제가 발생할 것입니다. 이때는 custom deleter를 구현해주어야 
합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래는 malloc으로 할당하고 custom deleter를 통해 해제하는 예입니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;struct my_free&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void operator()(void* x) { free(x); }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unique_ptr&amp;lt;int, my_free&amp;gt; a((int*)malloc(sizeof(int)));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;추가정보1. WebKit에서는 OwnPtr이란 것을 사용했지만, c++11을 사용할 수 있게 된 이후, 현재 unique_ptr로 변경하는 추세입니다.&lt;/p&gt;&lt;p&gt;추가정보2 : c++14 에서는 unique_ptr의 factory인 make_unique가 도입될 듯 합니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참조 (custom deleter) : http://stackoverflow.com/questions/3477525/is-it-possible-to-use-a-c-smart-pointers-together-with-cs-malloc&lt;/p&gt;&lt;p&gt;참조 : http://en.wikipedia.org/wiki/Smart_pointer#C.2B.2B_smart_pointers&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <category>C++11</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/407</guid>
      <comments>https://bunhere.tistory.com/407#entry407comment</comments>
      <pubDate>Fri, 1 Nov 2013 23:40:26 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] Type Inference: auto</title>
      <link>https://bunhere.tistory.com/406</link>
      <description>&lt;p&gt;&lt;b&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/405&quot;&gt;&lt;span style=&quot;background-color: rgb(154, 165, 234);&quot;&gt;목차로 가기&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;개인적으로 공부한 내용들로, 내용이 완벽하지 않을 수 있습니다. 부족한 부분/틀린 부분에 대한 Comment 환영합니다.&amp;gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;- 업데이트&lt;br /&gt;&amp;nbsp;* ts님이 지적해주신 제목 오타 수정&lt;br /&gt;&lt;br /&gt;&lt;p&gt;C/C++(C++11 이전의 C++)은 어떤 변수를 사용하려면 변수의 타입을 지정하여 선언(Declaration)을 해야만 합니다. 예를 들면 아래처럼 말입니다.&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;int a;&lt;/p&gt;&lt;p&gt;char b;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;그러나, 템플릿과 STL등을 사용하다보면 어떤 타입을 지정하여 선언한다는 것이 간단한 일이 아닙니다.&lt;/p&gt;&lt;p&gt;예를 들어 아래처럼 복잡한 타입을 선언해야 할 수 있습니다. (내용은 타 코드에서 아무렇게나 가져왔습니다.)&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;HashMap&amp;lt;int, RefPtr&amp;lt;StaticPropertyAnalysis&amp;gt;, 
WTF::IntHash&amp;lt;int&amp;gt;, 
WTF::UnsignedWithZeroKeyHashTraits&amp;lt;int&amp;gt;&amp;gt; map = getMap();&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이를 위해 C++11에서 등장한 두가지 타입 추론(Type Inference) 방법중 하나가 바로 auto 입니다.&lt;/p&gt;&lt;p&gt;위 문장은 간단히&amp;nbsp; 아래와 같이 선언할 수 있습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;auto map = getMap();&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;위 문장에서 map의 타입은 compile타임에 getMap의 반환값의 타입에 맞춰 변환될 것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사실 기존에 auto라는 키워드가 이미 존재했습니다. 스토리지 클래스(storage class)들 중 하나로 지역 변수(local variable)들의 기본 스토리지 클래스였습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 때 사용하던 auto의 용법은 아래와 같습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c&lt;/p&gt;&lt;p&gt;auto int i;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그러나 c++11을 사용하면 이 구문은 더이상 유효하지 않습니다.&lt;/p&gt;&lt;p&gt;다시말해, 위 예제를 그냥 c++11이전의 표준 컴파일러로 빌드하면 문제가 없지만 c++11 컴파일러로 빌드하면, 아래와 같은 에러가 발생합니다. (gcc 기준)&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;auto.cpp: In function ‘int main()’:&lt;br /&gt;auto.cpp:5:14: error: two or more data types in declaration of ‘i’&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;기존의 auto는 머리속에서 지워버리고(최소한 c++에서는), 이제 c++11에서 다시 등장한 auto에 익숙해지기 위해 몇가지 예제를 보도록 하겠습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;br /&gt;&lt;/p&gt;&lt;p&gt;auto i = 5; // i는 integer입니다.&lt;br /&gt;auto str = &quot;string&quot;; // str은 string입니다.&lt;br /&gt;auto* p = new Person; // p는 Person*입니다.&lt;br /&gt;const auto* cp = p; // cp는 const Person*입니다.&lt;br /&gt;auto&amp;amp; r = *p; // r는 Person&amp;amp;입니다.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위 코드를 디버거(gdb)로 실행해보면 아래와 같은 값들을 얻을 수 있습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;(gdb) p str&lt;br /&gt;$7 = 0x40095c &quot;str&quot;&lt;br /&gt;(gdb) p i&lt;br /&gt;$8 = 5&lt;br /&gt;(gdb) p p&lt;br /&gt;$9 = (Person *) 0x602010&lt;br /&gt;(gdb) p cp&lt;br /&gt;$10 = (const Person *) 0x602010&lt;br /&gt;(gdb) p r&lt;br /&gt;$11 = (Person &amp;amp;) @0x602010: {name = 0x400960 &quot;ryuan&quot;}&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;auto의 위력은 STL을 이용해 반환값을 선언하거나, iterator와 같은 코드를 구현할 때 진가를 발휘합니다.&lt;/p&gt;&lt;p&gt;예를 들어, 아래는 vector를 탐색하는 흔한 for loop입니다.&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;for (std::vector&amp;lt;int&amp;gt;::const_iterator itr = myvec.cbegin(); itr != myvec.cend(); ++itr)&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;이것을 auto를 이용하면 아래와 같습니다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;### c++&lt;/p&gt;&lt;p&gt;for (auto itr = myvec.cbegin(); itr != myvec.cend(); ++itr)&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참조 1 : &lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/C%2B%2B11&quot;&gt;http://en.wikipedia.org/wiki/C%2B%2B11&lt;/a&gt;&lt;/p&gt;&lt;p&gt;참조 2 : &lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2546.htm&quot;&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2546.htm&lt;/a&gt;&lt;/p&gt;&lt;p&gt;참조 3 (storage class) : http://msdn.microsoft.com/en-us/library/w9hwbe3d%28v=vs.80%29.ASPX&lt;br /&gt;&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <category>C++11</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/406</guid>
      <comments>https://bunhere.tistory.com/406#entry406comment</comments>
      <pubDate>Fri, 1 Nov 2013 22:56:48 +0900</pubDate>
    </item>
    <item>
      <title>c++11 스터디(목차)</title>
      <link>https://bunhere.tistory.com/405</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;C++11에 대한 개인적인 스터디 글들입니다.&lt;/p&gt;&lt;p&gt;&amp;lt;개인적으로 공부한 내용들로, 내용이 완벽하지 않을 수 있습니다. 부족한 부분/틀린 부분에 대한 Comment 환영합니다.&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt; &lt;/span&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/406&quot;&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;[C++11] Type Inference : auto&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;* &lt;/span&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/407&quot;&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;[C++11] &lt;/span&gt;&lt;/a&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/407&quot;&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;unique_ptr&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/408&quot;&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;* [C++11] Variadic template&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/409&quot;&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;* [C++11] rvalue reference&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/410&quot;&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;* [C++11] Move semantics&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://bunhere.tistory.com/411&quot;&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;* [C++11] Range based for loop&lt;br /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;계속 추가 예정입니다만. 언제 될지는 미정입니다.&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;GCC 버전별 C++0x/C++11 지원 현황 : &lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://gcc.gnu.org/projects/cxx0x.html&quot;&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;링크&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>프로그래밍 언어/C&amp;amp;C++</category>
      <category>C++11</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/405</guid>
      <comments>https://bunhere.tistory.com/405#entry405comment</comments>
      <pubDate>Fri, 1 Nov 2013 21:34:50 +0900</pubDate>
    </item>
    <item>
      <title>Elementary Dark theme</title>
      <link>https://bunhere.tistory.com/402</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 650px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2642543D525FB0A131&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2642543D525FB0A131&quot; width=&quot;650&quot; height=&quot;366&quot; filename=&quot;shot-2013-10-17_18-38-19.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;최신 Elementary를 빌드하면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;전체적으로 버튼 사이즈가 작아졌네요.&lt;br /&gt;&lt;/p&gt;</description>
      <category>개발</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/402</guid>
      <comments>https://bunhere.tistory.com/402#entry402comment</comments>
      <pubDate>Thu, 17 Oct 2013 18:41:35 +0900</pubDate>
    </item>
    <item>
      <title>[TIZEN][EFL] 타이젠 상에서 EFL 예제 실행하기</title>
      <link>https://bunhere.tistory.com/398</link>
      <description>&lt;p&gt;Tizen SDK 2.2부터는 EFL 개발을 할 수 있습니다. ( &lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;http://seoz.egloos.com/3969850&quot;&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;Tizen 2.2 정식 SDK 배포&lt;/span&gt;&lt;/a&gt; by SeoZ )&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 94, 0);&quot;&gt;단, Tizen을 설치하실 때 Platform Development를 선택하셔야 하고 리눅스에서만 개발이 가능합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 글은 우분투 (13.04)에서 작성하였습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;먼저 Tizen IDE를 실행하시고 New -&amp;gt; Others를 선택합니다.&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 613px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2239473A51FBD51B2F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2239473A51FBD51B2F&quot; width=&quot;613&quot; height=&quot;500&quot; filename=&quot;Screenshot from 2013-08-02 22:42:07.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Tizen 폴더를 선택하여 Tizen Platform Project를 선택합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 650px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/274D1D3A51FBD51C2B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F274D1D3A51FBD51C2B&quot; width=&quot;650&quot; height=&quot;557&quot; filename=&quot;Screenshot from 2013-08-02 22:42:29.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Template이 나오고 3가지 방법이 있습니다. 다음 릴리즈에는 Sample들도 추가되길 기대해 봅니다.&lt;/p&gt;&lt;p&gt;EFL Application을 선택합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 650px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/257C2E3A51FBD51D3A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F257C2E3A51FBD51D3A&quot; width=&quot;650&quot; height=&quot;557&quot; filename=&quot;Screenshot from 2013-08-02 22:43:02.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Hello EFL이라는 메뉴를 선택하고 Project name(여기서는 helloEFL)을 지정합니다.&lt;/p&gt;&lt;p&gt;Finish를 눌러 완료합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 390px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2545343A51FBD51E19&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2545343A51FBD51E19&quot; width=&quot;390&quot; height=&quot;405&quot; filename=&quot;Screenshot from 2013-08-03 00:05:13.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;그러면 Project Explore에 위와 같이 helloEFL이라는 프로젝트가 생겼음을 알 수 있습니다.&lt;/p&gt;&lt;p&gt;프로젝트는 총 4개의 폴더와 4개의 파일로 이루어져 있습니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;include/&lt;/b&gt; - 헤더파일들을 모아두는 곳입니다. 지금은 dbg.h라는 디버깅 정보를 출력하기 위한 헤더가 들어있습니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;packaging/&lt;/b&gt; - Tizen에서 platform개발은 rpm파일을 생성하여 이루어집니다. rpm파일 생성을 위한 정보는 spec에 지정하게 되어 있습니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;po/&lt;/b&gt; - 다국어 지원을 위한 메타 파일들이 들어있습니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;src/&lt;/b&gt; - 소스 코드들을 모아두는 폴더입니다. 지금은 main.c만 존재합니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;CMakeLists.txt&lt;/b&gt; - Tizen은 빌드 스크립트로 CMakefile을 선호합니다.(Autotools도 동작합니다.) main.c와 인클루드 정보등 빌드 정보를 담은 CMakeLists.txt가 존재합니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;org.tizen.helloEFL.png&lt;/b&gt; - 이 앱을 설치했을때 나오는 기본 아이콘입니다. 밋밋한 회색 원판입니다.(타이젠 로고라도 넣어줬으면 좋았을텐데 말입니다.)&lt;/p&gt;&lt;p&gt;&lt;b&gt;org.tizen.helloEFL.xml.in&lt;/b&gt; - 메니페스트 정보를 담는 파일입니다. 빌드를 하면 이 파일을 바탕으로 org.tizen.helloEFL.xml이 생성됩니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;일단 예제 실행을 위해 빌드를 해보겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;먼저 에뮬레이터가 실행되어 있는지 확인합니다.&lt;br /&gt;아래 그림처럼 Project explore 아래에 Connection Explore에 보면 현재 실행중인 에뮬레이터 정보가 보입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 380px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2616583551FBD8EA25&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2616583551FBD8EA25&quot; width=&quot;380&quot; height=&quot;630&quot; filename=&quot;Screenshot from 2013-08-03 01:01:54.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;없다면, 왼쪽에 휴대폰 모양의 버튼을 클릭해 줍니다. (현재 그림에는 한개의 에뮬레이터가 실행중입니다.)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그 다음 에뮬레이터를 root mode로 변환해야 합니다.(에뮬레이터는 한개만 실행중이라고 가정하겠습니다.)&lt;/p&gt;&lt;p&gt;콘솔창을 열어 아래 명령을 실행합니다.&lt;/p&gt;&lt;p&gt;# &lt;b&gt;sdb root on&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또 gbs가 설치되어 있어야 합니다.&lt;/p&gt;&lt;p&gt;gbs설치 방법에 대한 가이드는 source.tizen.org의 &lt;a class=&quot;tx-link&quot; target=&quot;_blank&quot; href=&quot;https://source.tizen.org/documentation/developer-guide/installing-development-tools&quot;&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;documentation&lt;/span&gt;&lt;/a&gt;에서 찾으실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;gbs 설치가 잘 되었다면 프로젝트 명에서 마우스 오른쪽 클릭을 하여 Run As -&amp;gt; Tizen Platform Project를 선택합니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;문제가 없다면 에뮬레이터 화면에서 Hello EFL 을 보실 수 있을 것입니다.&lt;/p&gt;&lt;p&gt;(gbs 빌드는 서버에서 의존성 패키지를 가져와 빌드하고 설치하는 과정을 거칩니다. 따라서 시간이 매우 오래 걸릴 수 있습니다.)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;몇가지 문제가 있을 수 있는데, 예를 들어 아래와 같은 상황입니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 223px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/274D513A51FBD51F04&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F274D513A51FBD51F04&quot; width=&quot;223&quot; height=&quot;154&quot; filename=&quot;Screenshot from 2013-08-03 00:12:16.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;이 팝업은 device가 root모드가 아니기 때문에 나타납니다.&lt;/p&gt;&lt;p&gt;sdb root on 을 실행해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 439px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2748B23A51FBD51F18&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2748B23A51FBD51F18&quot; width=&quot;439&quot; height=&quot;157&quot; filename=&quot;Screenshot from 2013-08-03 00:12:39.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;문제가 없으면 패키징을 할 것인지 물어봅니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 551px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2713FD3A51FBD52036&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2713FD3A51FBD52036&quot; width=&quot;551&quot; height=&quot;241&quot; filename=&quot;Screenshot from 2013-08-03 00:12:51.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;우분투의 경우 패키징을 위해 관리자 계정의 비밀번호가 필요합니다.(sudo의 비밀번호)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그림을 첨부하지 않았지만, gbs가 설치되어 있지 않으면 빌드 과정에서 실패가 될 것입니다.&lt;/p&gt;&lt;p&gt;이런 경우 gbs를 설치해 주셔야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;정상적으로 빌드된 후 실행되면 아래와 같은 간단한 EFL Application을 보실 수 있을 것입니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 412px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2753D43451FBD52116&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2753D43451FBD52116&quot; width=&quot;412&quot; height=&quot;692&quot; filename=&quot;Screenshot from 2013-08-03 00:48:08.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>개발</category>
      <category>EFL</category>
      <category>Tizen</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/398</guid>
      <comments>https://bunhere.tistory.com/398#entry398comment</comments>
      <pubDate>Fri, 2 Aug 2013 22:49:21 +0900</pubDate>
    </item>
    <item>
      <title>[TIZEN] 2.2 Emulator 실행하기</title>
      <link>https://bunhere.tistory.com/397</link>
      <description>&lt;p&gt;Tizen 2.2 에뮬레이터는 기존의 에뮬레이터보다 훨씬 예쁩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;에뮬레이터를 실행하면 아래와 같은 화면이 뜹니다.&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 650px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/270A973951FBB3A212&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F270A973951FBB3A212&quot; width=&quot;650&quot; height=&quot;394&quot; filename=&quot;Screenshot from 2013-08-01 22:08:46.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;가운데 + 버튼을 누르면 아래와 같은 화면이 나옵니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 650px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/23379A3951FBB3A309&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F23379A3951FBB3A309&quot; width=&quot;650&quot; height=&quot;394&quot; filename=&quot;Screenshot from 2013-08-01 22:13:22.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;입력해야 할 정보들은 예전과 유사하지만 디자인이 좀 더 예쁩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 650px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2752A63951FBB3A431&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2752A63951FBB3A431&quot; width=&quot;650&quot; height=&quot;394&quot; filename=&quot;Screenshot from 2013-08-01 22:15:06.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Name은 적절한 이름을 입력하고 (tizen),&lt;/p&gt;&lt;p&gt;Ram Size는 1025Mb로 늘렸습니다.&lt;/p&gt;&lt;p&gt;File Sharing을 켜고, [...]을 눌러 적절한 폴더를 선택했습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Confirm버튼을 누르면 아래와 같습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 650px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/275F303951FBB3A530&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F275F303951FBB3A530&quot; width=&quot;650&quot; height=&quot;394&quot; filename=&quot;Screenshot from 2013-08-01 22:15:23.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;왼쪽에 아래와 같이 입력된 간단한 정보를 보여주는 작은 휴대폰 모양이 생깁니다.&lt;/p&gt;&lt;p&gt;파일들은 ~/tizen-sdk-data/emulator-vms/vms 에 생성됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;휴대폰 모양안에 있는 파란 버튼을 클릭하면 아래처럼 에뮬레이터가 실행됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 650px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/254D073951FBB3A633&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F254D073951FBB3A633&quot; width=&quot;650&quot; height=&quot;366&quot; filename=&quot;Screenshot from 2013-08-01 22:20:51.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>개발</category>
      <author>소혼</author>
      <guid isPermaLink="true">https://bunhere.tistory.com/397</guid>
      <comments>https://bunhere.tistory.com/397#entry397comment</comments>
      <pubDate>Thu, 1 Aug 2013 22:22:32 +0900</pubDate>
    </item>
  </channel>
</rss>